Compare commits

..

3 Commits

Author SHA1 Message Date
Henry
be8795e34f fix: use debian to build migration image 2026-02-19 10:58:52 +00:00
Henry
cbf347dce0 fix: use correct org.opencontainers.image.version label 2026-02-18 23:21:36 +00:00
Henry
cb9736134d feat: publish migrator image 2026-02-18 23:15:19 +00:00
40 changed files with 28931 additions and 61536 deletions

View File

@@ -9,17 +9,11 @@ on:
schedule:
- cron: "21 21 * * *"
push:
# Only trigger on tags (releases), not main branch pushes
# Main branch builds are handled by workflow_run after Translate completes
branches: ["main"]
# Publish semver tags as releases.
tags: ["v*.*.*"]
pull_request:
branches: ["main"]
workflow_run:
workflows: ["Translate"]
types: [completed]
branches: [main]
# Docker builds after Translate completes (success or failure)
# This ensures Docker always has the latest translations
env:
# Use docker.io for Docker Hub if empty
@@ -29,9 +23,6 @@ env:
jobs:
build:
concurrency:
group: docker-build-${{ github.ref }}
cancel-in-progress: true
runs-on: ubuntu-latest
permissions:
contents: read
@@ -70,21 +61,6 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable={{is_default_branch}}
# Extract version from git tag or ref
# Uses git describe to get latest tag + commit hash in SemVer format: 1.2.3+abc1234
- name: Extract version
@@ -121,6 +97,39 @@ jobs:
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable={{is_default_branch}}
labels: |
org.opencontainers.image.version=${{ steps.version.outputs.version }}
# Extract metadata for migrate image
- name: Extract Docker metadata for migrate
id: meta-migrate
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-migrate
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable={{is_default_branch}}
labels: |
org.opencontainers.image.version=${{ steps.version.outputs.version }}
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
@@ -138,6 +147,24 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
# Build and push migrate Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push migrate Docker image
id: build-and-push-migrate
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
file: apps/web/Dockerfile
target: migrate
push: ${{ github.event_name != 'pull_request' }}
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta-migrate.outputs.tags }}
labels: ${{ steps.meta-migrate.outputs.labels }}
build-args: |
APP_VERSION=${{ steps.version.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Sign the resulting Docker image digest except on PRs.
# This will only write to the public Rekor transparency log when the Docker
# repository is public to avoid leaking data. If you would like to publish
@@ -152,3 +179,11 @@ jobs:
# This step uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
# Sign the migrate Docker image digest except on PRs.
- name: Sign the published migrate Docker image
if: ${{ github.event_name != 'pull_request' }}
env:
TAGS: ${{ steps.meta-migrate.outputs.tags }}
DIGEST: ${{ steps.build-and-push-migrate.outputs.digest }}
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}

View File

@@ -1,49 +0,0 @@
name: Translate
on:
push:
branches: [main]
permissions:
contents: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Extract translations
working-directory: apps/web
run: npx --yes @lingui/cli extract
- name: Lingo.dev
uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
commit-message: "chore: update translations"
working-directory: apps/web
commit-author-name: "${{ github.actor }}"
commit-author-email: "${{ github.actor }}@users.noreply.github.com"
parallel: true
- name: Compile translations
working-directory: apps/web
run: npx --yes @lingui/cli compile --typescript
- name: Commit compiled translations
run: |
git config --local user.email "${{ github.actor }}@users.noreply.github.com"
git config --local user.name "${{ github.actor }}"
if ls apps/web/src/locales/*/messages.ts 1> /dev/null 2>&1; then
git add apps/web/src/locales/*/messages.ts
git diff --staged --quiet || (git commit -m "chore: compile translations" && git push)
fi

View File

@@ -69,8 +69,11 @@ RUN VERSION="${APP_VERSION:-$(cat /tmp/AUTO_VERSION 2>/dev/null | tr -d '\n\r' |
# ============================================
# Stage 5: Migration image (run-once container)
# Note: Use a Debian-based Node image instead of Alpine here because
# Alpine under QEMU has caused Illegal instruction (signal 4) crashes
# during npm installs on arm64 multi-arch builds.
# ============================================
FROM node:${NODE_VERSION}-alpine AS migrate
FROM node:${NODE_VERSION}-bullseye-slim AS migrate
WORKDIR /db
COPY packages/db/drizzle.config.ts ./drizzle.config.ts

View File

@@ -1,12 +1,12 @@
{
"version": "1.10",
"version": 0,
"locale": {
"source": "en",
"targets": ["fr", "de", "es", "it", "nl", "ru", "pl", "pt-BR"]
},
"buckets": {
"json": {
"include": ["src/locales/[locale]/messages.json"]
"po": {
"include": ["src/locales/[locale]/messages.po"]
}
},
"$schema": "https://lingo.dev/schema/i18n.json"

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,7 @@
import { defineConfig } from "@lingui/cli";
import { formatter } from "@lingui/format-json";
import type { LinguiConfig } from "@lingui/conf";
export default defineConfig({
locales: ["en", "fr", "de", "es", "it", "nl", "ru", "pl", "pt-BR"],
const config: LinguiConfig = {
locales: ["en", "fr", "de", "es", "it", "nl", "ru", "pl","pt-BR"],
sourceLocale: "en",
catalogs: [
{
@@ -12,5 +10,6 @@ export default defineConfig({
exclude: ["**/node_modules/**"],
},
],
format: formatter({ style: "lingui" }),
});
};
export default config;

View File

@@ -47,13 +47,49 @@ const config = {
remotePatterns: (() => {
/** @type {Array<{protocol: "http" | "https", hostname: string}>} */
const patterns = [
{ protocol: "https", hostname: "**" },
{
protocol: "https",
hostname:
env("S3_FORCE_PATH_STYLE") === "true"
? `${env("NEXT_PUBLIC_STORAGE_DOMAIN")}`
: `*.${env("NEXT_PUBLIC_STORAGE_DOMAIN")}`,
},
{
protocol: "http",
hostname: "localhost",
},
{
protocol: "https",
hostname: "*.googleusercontent.com",
},
{
protocol: "https",
hostname: "cdn.discordapp.com",
},
];
// Extract root domain from S3_ENDPOINT and add wildcard pattern
const s3Endpoint = env("S3_ENDPOINT");
if (s3Endpoint) {
try {
const url = new URL(s3Endpoint);
const hostname = url.hostname;
const protocol = url.protocol.replace(":", "");
// Extract root domain (last 2 parts: e.g. cloudflarestorage.com)
const parts = hostname.split(".");
if (parts.length >= 2) {
const rootDomain = parts.slice(-2).join(".");
patterns.push({
protocol: protocol === "http" ? "http" : "https",
hostname: `*.${rootDomain}`,
});
}
} catch {
// If S3_ENDPOINT is not a valid URL, ignore it
}
}
return patterns;
})(),
},

View File

@@ -79,7 +79,6 @@
"@kan/tailwind-config": "workspace:*",
"@kan/tsconfig": "workspace:*",
"@lingui/cli": "^5.3.2",
"@lingui/format-json": "^5.9.1",
"@lingui/loader": "^5.3.2",
"@lingui/swc-plugin": "^5.5.2",
"@svgr/webpack": "^8.1.0",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,17 +1,4 @@
services:
migrator:
image: ghcr.io/kanbn/kan-migrate:latest
container_name: ${MIGRATOR_CONTAINER_NAME:-kan-migrate}
build:
context: ..
dockerfile: apps/web/Dockerfile
target: migrate
networks:
- dokploy-network
environment:
- POSTGRES_URL=${POSTGRES_URL}
restart: "no"
web:
image: ghcr.io/kanbn/kan:latest
container_name: ${CONTAINER_NAME:-kan-web}
@@ -22,7 +9,6 @@ services:
build:
context: ..
dockerfile: apps/web/Dockerfile
target: web
args:
APP_VERSION: ${APP_VERSION:-}
env_file:
@@ -93,9 +79,6 @@ services:
- NEXT_PUBLIC_UMAMI_ID=${NEXT_PUBLIC_UMAMI_ID}
- NEXT_PUBLIC_POSTHOG_KEY=${NEXT_PUBLIC_POSTHOG_KEY}
- NEXT_PUBLIC_POSTHOG_HOST=${NEXT_PUBLIC_POSTHOG_HOST}
depends_on:
migrator:
condition: service_completed_successfully
networks:
dokploy-network:

View File

@@ -210,12 +210,11 @@ export const memberRouter = createTRPCRouter({
input.memberPublicId,
);
if (!member || member.workspaceId !== workspace.id) {
if (!member)
throw new TRPCError({
message: `Member with public ID ${input.memberPublicId} not found`,
code: "NOT_FOUND",
});
}
const deletedMember = await memberRepo.softDelete(ctx.db, {
memberId: member.id,
@@ -721,7 +720,7 @@ export const memberRouter = createTRPCRouter({
input.memberPublicId,
);
if (!member || member.workspaceId !== workspace.id) {
if (!member) {
throw new TRPCError({
message: "Member not found",
code: "NOT_FOUND",

View File

@@ -133,7 +133,7 @@ export const permissionRouter = createTRPCRouter({
input.memberPublicId,
);
if (!member || member.workspaceId !== workspace.id) {
if (!member) {
throw new TRPCError({
message: "Member not found",
code: "NOT_FOUND",
@@ -209,7 +209,7 @@ export const permissionRouter = createTRPCRouter({
input.memberPublicId,
);
if (!member || member.workspaceId !== workspace.id) {
if (!member) {
throw new TRPCError({
message: "Member not found",
code: "NOT_FOUND",
@@ -274,7 +274,7 @@ export const permissionRouter = createTRPCRouter({
input.memberPublicId,
);
if (!member || member.workspaceId !== workspace.id) {
if (!member) {
throw new TRPCError({
message: "Member not found",
code: "NOT_FOUND",
@@ -339,7 +339,7 @@ export const permissionRouter = createTRPCRouter({
input.memberPublicId,
);
if (!member || member.workspaceId !== workspace.id) {
if (!member) {
throw new TRPCError({
message: "Member not found",
code: "NOT_FOUND",

View File

@@ -7,8 +7,8 @@ import * as memberRepo from "@kan/db/repository/member.repo";
import * as subscriptionRepo from "@kan/db/repository/subscription.repo";
import * as userRepo from "@kan/db/repository/user.repo";
import * as workspaceRepo from "@kan/db/repository/workspace.repo";
import { sendEmail } from "@kan/email";
import { generateUID } from "@kan/shared/utils";
import { sendEmail } from "@kan/email";
import { createStripeClient } from "@kan/stripe";
import { socialProvidersPlugin } from "./providers";
@@ -139,11 +139,10 @@ export function createPlugins(db: dbClient) {
let newSlug = workspace.publicId;
if (workspace.slug !== workspace.publicId) {
const isPublicIdAvailable =
await workspaceRepo.isWorkspaceSlugAvailable(
db,
workspace.publicId,
);
const isPublicIdAvailable = await workspaceRepo.isWorkspaceSlugAvailable(
db,
workspace.publicId,
);
if (!isPublicIdAvailable) {
newSlug = generateUID();
}
@@ -173,77 +172,69 @@ export function createPlugins(db: dbClient) {
magicLink({
expiresIn: 60 * 60 * 24 * 7, // 7 days
sendMagicLink: async ({ email, url }) => {
try {
const decodedUrl = decodeURIComponent(url);
console.log("Sending magic link to:", email, "URL:", url);
console.log(
"Magic link contains invite:",
decodedUrl.includes("type=invite"),
);
if (decodedUrl.includes("type=invite")) {
let inviterName = "";
let workspaceName = "";
const decodedUrl = decodeURIComponent(url);
console.log("Sending magic link to:", email, "URL:", url);
console.log(
"Magic link contains invite:",
decodedUrl.includes("type=invite"),
);
if (decodedUrl.includes("type=invite")) {
let inviterName = "";
let workspaceName = "";
try {
const urlObj = new URL(url);
const callbackUrl = urlObj.searchParams.get("callbackURL");
if (callbackUrl) {
const callbackParams = new URL(
callbackUrl,
process.env.NEXT_PUBLIC_BASE_URL,
).searchParams;
const memberPublicId = callbackParams.get("memberPublicId");
try {
const urlObj = new URL(url);
const callbackUrl = urlObj.searchParams.get("callbackURL");
if (callbackUrl) {
const callbackParams = new URL(
callbackUrl,
process.env.NEXT_PUBLIC_BASE_URL,
).searchParams;
const memberPublicId = callbackParams.get("memberPublicId");
if (memberPublicId) {
const member = await memberRepo.getByPublicId(
db,
memberPublicId,
);
if (member) {
const [workspace, inviter] = await Promise.all([
workspaceRepo.getById(db, member.workspaceId),
userRepo.getById(db, member.createdBy),
]);
if (memberPublicId) {
const member = await memberRepo.getByPublicId(
db,
memberPublicId,
);
if (member) {
const [workspace, inviter] = await Promise.all([
workspaceRepo.getById(db, member.workspaceId),
userRepo.getById(db, member.createdBy),
]);
if (workspace) workspaceName = workspace.name;
if (inviter) inviterName = inviter.name ?? "";
}
if (workspace) workspaceName = workspace.name;
if (inviter) inviterName = inviter.name ?? "";
}
}
} catch (error) {
console.error("Failed to fetch invite details:", error);
}
await sendEmail(
email,
workspaceName
? `Invitation to join the workspace ${workspaceName}`
: "Invitation to join workspace",
"JOIN_WORKSPACE",
{
magicLoginUrl: url,
inviterName,
workspaceName,
},
);
} else {
await sendEmail(
email,
process.env.NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY === "true"
? "Sign in to your account"
: "Sign in to Kan",
"MAGIC_LINK",
{
magicLoginUrl: url,
},
);
} catch (error) {
console.error("Failed to fetch invite details:", error);
}
} catch (error) {
console.error("Error sending magic link:", {
await sendEmail(
email,
url,
error,
});
workspaceName
? `Invitation to join the workspace ${workspaceName}`
: "Invitation to join workspace",
"JOIN_WORKSPACE",
{
magicLoginUrl: url,
inviterName,
workspaceName,
},
);
} else {
await sendEmail(
email,
process.env.NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY === "true"
? "Sign in to your account"
: "Sign in to Kan",
"MAGIC_LINK",
{
magicLoginUrl: url,
},
);
}
},
}),

143
pnpm-lock.yaml generated
View File

@@ -254,9 +254,6 @@ importers:
'@lingui/cli':
specifier: ^5.3.2
version: 5.4.1(typescript@5.9.2)
'@lingui/format-json':
specifier: ^5.9.1
version: 5.9.1(typescript@5.9.2)
'@lingui/loader':
specifier: ^5.3.2
version: 5.4.1(typescript@5.9.2)(webpack@5.101.3)
@@ -344,7 +341,7 @@ importers:
version: link:../../tooling/typescript
eslint:
specifier: 'catalog:'
version: 9.34.0(jiti@2.6.1)
version: 9.34.0(jiti@2.4.2)
prettier:
specifier: 'catalog:'
version: 3.6.2
@@ -384,7 +381,7 @@ importers:
version: link:../../tooling/typescript
eslint:
specifier: 'catalog:'
version: 9.34.0(jiti@2.6.1)
version: 9.34.0(jiti@2.4.2)
prettier:
specifier: 'catalog:'
version: 3.6.2
@@ -439,7 +436,7 @@ importers:
version: 0.28.1
eslint:
specifier: 'catalog:'
version: 9.34.0(jiti@2.6.1)
version: 9.34.0(jiti@2.4.2)
prettier:
specifier: 'catalog:'
version: 3.6.2
@@ -476,7 +473,7 @@ importers:
version: 6.4.19
eslint:
specifier: 'catalog:'
version: 9.34.0(jiti@2.6.1)
version: 9.34.0(jiti@2.4.2)
prettier:
specifier: 'catalog:'
version: 3.6.2
@@ -516,7 +513,7 @@ importers:
version: link:../../tooling/typescript
eslint:
specifier: 'catalog:'
version: 9.34.0(jiti@2.6.1)
version: 9.34.0(jiti@2.4.2)
prettier:
specifier: 'catalog:'
version: 3.6.2
@@ -541,7 +538,7 @@ importers:
version: link:../../tooling/typescript
eslint:
specifier: 'catalog:'
version: 9.34.0(jiti@2.6.1)
version: 9.34.0(jiti@2.4.2)
prettier:
specifier: 'catalog:'
version: 3.6.2
@@ -553,28 +550,28 @@ importers:
dependencies:
'@eslint/compat':
specifier: ^1.2.3
version: 1.3.2(eslint@9.34.0(jiti@2.6.1))
version: 1.3.2(eslint@9.34.0(jiti@2.4.2))
'@next/eslint-plugin-next':
specifier: ^14.2.15
version: 14.2.32
eslint-plugin-import:
specifier: ^2.31.0
version: 2.32.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1))
version: 2.32.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2))(eslint@9.34.0(jiti@2.4.2))
eslint-plugin-jsx-a11y:
specifier: ^6.10.2
version: 6.10.2(eslint@9.34.0(jiti@2.6.1))
version: 6.10.2(eslint@9.34.0(jiti@2.4.2))
eslint-plugin-react:
specifier: ^7.37.2
version: 7.37.5(eslint@9.34.0(jiti@2.6.1))
version: 7.37.5(eslint@9.34.0(jiti@2.4.2))
eslint-plugin-react-hooks:
specifier: ^5.0.0
version: 5.2.0(eslint@9.34.0(jiti@2.6.1))
version: 5.2.0(eslint@9.34.0(jiti@2.4.2))
eslint-plugin-turbo:
specifier: ^2.3.1
version: 2.5.6(eslint@9.34.0(jiti@2.6.1))(turbo@2.5.6)
version: 2.5.6(eslint@9.34.0(jiti@2.4.2))(turbo@2.5.6)
typescript-eslint:
specifier: ^8.15.0
version: 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)
version: 8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)
devDependencies:
'@kan/prettier-config':
specifier: workspace:*
@@ -587,7 +584,7 @@ importers:
version: 8.42.3
eslint:
specifier: 'catalog:'
version: 9.34.0(jiti@2.6.1)
version: 9.34.0(jiti@2.4.2)
prettier:
specifier: 'catalog:'
version: 3.6.2
@@ -640,7 +637,7 @@ importers:
version: link:../typescript
eslint:
specifier: 'catalog:'
version: 9.34.0(jiti@2.6.1)
version: 9.34.0(jiti@2.4.2)
prettier:
specifier: 'catalog:'
version: 3.6.2
@@ -2676,10 +2673,6 @@ packages:
resolution: {integrity: sha512-aDkj/bMSr/mCL8Nr1TS52v0GLCuVa4YqtRz+WvUCFZw/ovVInX0hKq1TClx/bSlhu60FzB/CbclxFMBw8aLVUg==}
engines: {node: '>=20.0.0'}
'@lingui/conf@5.9.1':
resolution: {integrity: sha512-Dr1CV4P3INJZZzvLcksgML4kusHQS3pJyONcZt40l/T74LOETUSk2cxFW5epizWU46FpN2ThusvC2yb0L8o1jA==}
engines: {node: '>=20.0.0'}
'@lingui/core@5.4.1':
resolution: {integrity: sha512-4FeIh56PH5vziPg2BYo4XYWWOHE4XaY/XR8Jakwn0/qwtLpydWMNVpZOpGWi7nfPZtcLaJLmZKup6UNxEl1Pfw==}
engines: {node: '>=20.0.0'}
@@ -2692,10 +2685,6 @@ packages:
babel-plugin-macros:
optional: true
'@lingui/format-json@5.9.1':
resolution: {integrity: sha512-Kp/saH3jKJPlAzjcDJd+yqePoC6PZOc8cbO1mL/mN8mOz5bF9w+LnX4KntgZz1MjJwP12fqtGbr6AxDevwnmWw==}
engines: {node: '>=20.0.0'}
'@lingui/format-po@5.4.1':
resolution: {integrity: sha512-IBVq3RRLNEVRzNZcdEw0qpM5NKX4e9wDmvJMorkR2OYrgTbhWx5gDYhXpEZ9yqtuEVhILMdriVNjAAUnDAJibA==}
engines: {node: '>=20.0.0'}
@@ -6168,10 +6157,6 @@ packages:
resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
hasBin: true
jiti@2.6.1:
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
hasBin: true
jose@6.1.2:
resolution: {integrity: sha512-MpcPtHLE5EmztuFIqB0vzHAWJPpmN1E6L4oo+kze56LIs3MyXIj9ZHMDxqOvkP38gBR7K1v3jqd4WU2+nrfONQ==}
@@ -10466,16 +10451,16 @@ snapshots:
eslint: 9.34.0(jiti@1.21.7)
eslint-visitor-keys: 3.4.3
'@eslint-community/eslint-utils@4.7.0(eslint@9.34.0(jiti@2.6.1))':
'@eslint-community/eslint-utils@4.7.0(eslint@9.34.0(jiti@2.4.2))':
dependencies:
eslint: 9.34.0(jiti@2.6.1)
eslint: 9.34.0(jiti@2.4.2)
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.1': {}
'@eslint/compat@1.3.2(eslint@9.34.0(jiti@2.6.1))':
'@eslint/compat@1.3.2(eslint@9.34.0(jiti@2.4.2))':
optionalDependencies:
eslint: 9.34.0(jiti@2.6.1)
eslint: 9.34.0(jiti@2.4.2)
'@eslint/config-array@0.21.0':
dependencies:
@@ -10886,16 +10871,6 @@ snapshots:
transitivePeerDependencies:
- typescript
'@lingui/conf@5.9.1(typescript@5.9.2)':
dependencies:
'@babel/runtime': 7.28.3
cosmiconfig: 8.3.6(typescript@5.9.2)
jest-validate: 29.7.0
jiti: 2.6.1
picocolors: 1.1.1
transitivePeerDependencies:
- typescript
'@lingui/core@5.4.1(@lingui/babel-plugin-lingui-macro@5.4.1(typescript@5.9.2))':
dependencies:
'@babel/runtime': 7.28.3
@@ -10903,12 +10878,6 @@ snapshots:
optionalDependencies:
'@lingui/babel-plugin-lingui-macro': 5.4.1(typescript@5.9.2)
'@lingui/format-json@5.9.1(typescript@5.9.2)':
dependencies:
'@lingui/conf': 5.9.1(typescript@5.9.2)
transitivePeerDependencies:
- typescript
'@lingui/format-po@5.4.1(typescript@5.9.2)':
dependencies:
'@lingui/conf': 5.4.1(typescript@5.9.2)
@@ -12570,15 +12539,15 @@ snapshots:
dependencies:
'@types/yargs-parser': 21.0.3
'@typescript-eslint/eslint-plugin@8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)':
'@typescript-eslint/eslint-plugin@8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2))(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)':
dependencies:
'@eslint-community/regexpp': 4.12.1
'@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)
'@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)
'@typescript-eslint/scope-manager': 8.41.0
'@typescript-eslint/type-utils': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)
'@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)
'@typescript-eslint/type-utils': 8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)
'@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)
'@typescript-eslint/visitor-keys': 8.41.0
eslint: 9.34.0(jiti@2.6.1)
eslint: 9.34.0(jiti@2.4.2)
graphemer: 1.4.0
ignore: 7.0.5
natural-compare: 1.4.0
@@ -12587,14 +12556,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)':
'@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)':
dependencies:
'@typescript-eslint/scope-manager': 8.41.0
'@typescript-eslint/types': 8.41.0
'@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2)
'@typescript-eslint/visitor-keys': 8.41.0
debug: 4.4.3
eslint: 9.34.0(jiti@2.6.1)
eslint: 9.34.0(jiti@2.4.2)
typescript: 5.9.2
transitivePeerDependencies:
- supports-color
@@ -12617,13 +12586,13 @@ snapshots:
dependencies:
typescript: 5.9.2
'@typescript-eslint/type-utils@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)':
'@typescript-eslint/type-utils@8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)':
dependencies:
'@typescript-eslint/types': 8.41.0
'@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2)
'@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)
'@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)
debug: 4.4.3
eslint: 9.34.0(jiti@2.6.1)
eslint: 9.34.0(jiti@2.4.2)
ts-api-utils: 2.1.0(typescript@5.9.2)
typescript: 5.9.2
transitivePeerDependencies:
@@ -12647,13 +12616,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)':
'@typescript-eslint/utils@8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)':
dependencies:
'@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.6.1))
'@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.4.2))
'@typescript-eslint/scope-manager': 8.41.0
'@typescript-eslint/types': 8.41.0
'@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2)
eslint: 9.34.0(jiti@2.6.1)
eslint: 9.34.0(jiti@2.4.2)
typescript: 5.9.2
transitivePeerDependencies:
- supports-color
@@ -13979,17 +13948,17 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.34.0(jiti@2.6.1)):
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.34.0(jiti@2.4.2)):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)
eslint: 9.34.0(jiti@2.6.1)
'@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)
eslint: 9.34.0(jiti@2.4.2)
eslint-import-resolver-node: 0.3.9
transitivePeerDependencies:
- supports-color
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1)):
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2))(eslint@9.34.0(jiti@2.4.2)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@@ -13998,9 +13967,9 @@ snapshots:
array.prototype.flatmap: 1.3.3
debug: 3.2.7
doctrine: 2.1.0
eslint: 9.34.0(jiti@2.6.1)
eslint: 9.34.0(jiti@2.4.2)
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.34.0(jiti@2.6.1))
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.34.0(jiti@2.4.2))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@@ -14012,13 +13981,13 @@ snapshots:
string.prototype.trimend: 1.0.9
tsconfig-paths: 3.15.0
optionalDependencies:
'@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)
'@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- supports-color
eslint-plugin-jsx-a11y@6.10.2(eslint@9.34.0(jiti@2.6.1)):
eslint-plugin-jsx-a11y@6.10.2(eslint@9.34.0(jiti@2.4.2)):
dependencies:
aria-query: 5.3.2
array-includes: 3.1.9
@@ -14028,7 +13997,7 @@ snapshots:
axobject-query: 4.1.0
damerau-levenshtein: 1.0.8
emoji-regex: 9.2.2
eslint: 9.34.0(jiti@2.6.1)
eslint: 9.34.0(jiti@2.4.2)
hasown: 2.0.2
jsx-ast-utils: 3.3.5
language-tags: 1.0.9
@@ -14037,11 +14006,11 @@ snapshots:
safe-regex-test: 1.1.0
string.prototype.includes: 2.0.1
eslint-plugin-react-hooks@5.2.0(eslint@9.34.0(jiti@2.6.1)):
eslint-plugin-react-hooks@5.2.0(eslint@9.34.0(jiti@2.4.2)):
dependencies:
eslint: 9.34.0(jiti@2.6.1)
eslint: 9.34.0(jiti@2.4.2)
eslint-plugin-react@7.37.5(eslint@9.34.0(jiti@2.6.1)):
eslint-plugin-react@7.37.5(eslint@9.34.0(jiti@2.4.2)):
dependencies:
array-includes: 3.1.9
array.prototype.findlast: 1.2.5
@@ -14049,7 +14018,7 @@ snapshots:
array.prototype.tosorted: 1.1.4
doctrine: 2.1.0
es-iterator-helpers: 1.2.1
eslint: 9.34.0(jiti@2.6.1)
eslint: 9.34.0(jiti@2.4.2)
estraverse: 5.3.0
hasown: 2.0.2
jsx-ast-utils: 3.3.5
@@ -14063,10 +14032,10 @@ snapshots:
string.prototype.matchall: 4.0.12
string.prototype.repeat: 1.0.0
eslint-plugin-turbo@2.5.6(eslint@9.34.0(jiti@2.6.1))(turbo@2.5.6):
eslint-plugin-turbo@2.5.6(eslint@9.34.0(jiti@2.4.2))(turbo@2.5.6):
dependencies:
dotenv: 16.0.3
eslint: 9.34.0(jiti@2.6.1)
eslint: 9.34.0(jiti@2.4.2)
turbo: 2.5.6
eslint-scope@5.1.1:
@@ -14125,9 +14094,9 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint@9.34.0(jiti@2.6.1):
eslint@9.34.0(jiti@2.4.2):
dependencies:
'@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.6.1))
'@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.4.2))
'@eslint-community/regexpp': 4.12.1
'@eslint/config-array': 0.21.0
'@eslint/config-helpers': 0.3.1
@@ -14163,7 +14132,7 @@ snapshots:
natural-compare: 1.4.0
optionator: 0.9.4
optionalDependencies:
jiti: 2.6.1
jiti: 2.4.2
transitivePeerDependencies:
- supports-color
@@ -14954,8 +14923,6 @@ snapshots:
jiti@2.4.2: {}
jiti@2.6.1: {}
jose@6.1.2: {}
jose@6.1.3: {}
@@ -17718,13 +17685,13 @@ snapshots:
possible-typed-array-names: 1.1.0
reflect.getprototypeof: 1.0.10
typescript-eslint@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2):
typescript-eslint@8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2):
dependencies:
'@typescript-eslint/eslint-plugin': 8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)
'@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)
'@typescript-eslint/eslint-plugin': 8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2))(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)
'@typescript-eslint/parser': 8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)
'@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2)
'@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.6.1))(typescript@5.9.2)
eslint: 9.34.0(jiti@2.6.1)
'@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.4.2))(typescript@5.9.2)
eslint: 9.34.0(jiti@2.4.2)
typescript: 5.9.2
transitivePeerDependencies:
- supports-color