Compare commits
16
Commits
cab4280e63
...
v1.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01a297884a | ||
|
|
01196b0843 | ||
|
|
48bdd6f2e6 | ||
|
|
2d003a2101 | ||
|
|
2f5d2b6e09 | ||
|
|
f31afb5318 | ||
|
|
b12eaeef82 | ||
|
|
c6905d3865 | ||
|
|
8876b38f0a | ||
|
|
02280d0f42 | ||
|
|
f43bb234ab | ||
|
|
dacc4cadfd | ||
|
|
65f118c918 | ||
|
|
cc458332d7 | ||
|
|
3f43a62243 | ||
|
|
5f98b949ad |
No files matched your search
@@ -1,10 +1,5 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "feat/**"
|
||||
- "fix/**"
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
@@ -13,7 +8,7 @@ jobs:
|
||||
check:
|
||||
runs-on: shell
|
||||
steps:
|
||||
- name: Typecheck, lint, security audit, and test
|
||||
- name: Typecheck, lint, and test
|
||||
run: |
|
||||
set -e
|
||||
WORK="$(mktemp -d /var/tmp/epicnext-ci.XXXXXX)"
|
||||
@@ -38,10 +33,8 @@ jobs:
|
||||
export ARGON2_MEMORY_SIZE=1024
|
||||
export ARGON2_ITERATIONS=1
|
||||
export BCRYPT_ROUNDS=4
|
||||
export DATABASE_URL="mysql://ci:[email protected]:3306/ci"
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm prisma:generate
|
||||
pnpm audit --audit-level=high || echo "WARNING: pnpm audit found high/critical vulnerabilities"
|
||||
pnpm biome:lint
|
||||
pnpm typecheck
|
||||
pnpm test
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
name: Renovate
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 5 * * *" # every day at 05:00
|
||||
workflow_dispatch: # manual trigger
|
||||
- cron: "0 5 * * *" # Every day at 05:00 UTC
|
||||
workflow_dispatch: # Manual trigger
|
||||
|
||||
jobs:
|
||||
renovate:
|
||||
@@ -11,7 +11,13 @@ jobs:
|
||||
- name: Self-hosted Renovate
|
||||
run: |
|
||||
set -e
|
||||
|
||||
# Zorg ervoor dat de cache-map lokaal bestaat vóór Docker start
|
||||
# Dit voorkomt dat Docker de map automatisch als 'root' aanmaakt
|
||||
mkdir -p /var/tmp/renovate-cache
|
||||
|
||||
docker run --rm \
|
||||
--user "$(id -u):$(id -g)" \
|
||||
-e RENOVATE_TOKEN="${{ secrets.RENOVATE_TOKEN }}" \
|
||||
-e RENOVATE_AUTODISCOVER=false \
|
||||
-e RENOVATE_REPOSITORIES="${{ gitea.repository }}" \
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.5.5/schema.json",
|
||||
"$schema": "https://biomejs.dev",
|
||||
"vcs": {
|
||||
"enabled": true,
|
||||
"clientKind": "git",
|
||||
|
||||
+27
-1
@@ -1,4 +1,7 @@
|
||||
import js from "@eslint/js";
|
||||
import nextPlugin from "@next/eslint-plugin-next";
|
||||
import reactHooks from "eslint-plugin-react-hooks";
|
||||
import security from "eslint-plugin-security";
|
||||
import unusedImports from "eslint-plugin-unused-imports";
|
||||
import tseslint from "typescript-eslint";
|
||||
|
||||
@@ -12,9 +15,32 @@ export default tseslint.config(
|
||||
files: ["src/**/*.{ts,tsx}", "pages/**/*.{ts,tsx}", "app/**/*.{ts,tsx}"],
|
||||
plugins: {
|
||||
"unused-imports": unusedImports,
|
||||
security: security,
|
||||
"react-hooks": reactHooks,
|
||||
"@next/next": nextPlugin,
|
||||
},
|
||||
rules: {
|
||||
"unused-imports/no-unused-vars": "error",
|
||||
// Laad automatisch alle aanbevolen beveiligings- en framework-regels in
|
||||
...security.configs.recommended.rules,
|
||||
...reactHooks.configs.recommended.rules,
|
||||
...nextPlugin.configs.recommended.rules,
|
||||
|
||||
// Zorg dat variabelen die beginnen met een underscore (_req) genegeerd worden
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
"unused-imports/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
|
||||
"no-console": "warn",
|
||||
},
|
||||
},
|
||||
|
||||
+30
-26
@@ -11,7 +11,7 @@
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"prisma:generate": "prisma generate",
|
||||
"typecheck": "tsc --noEmit --incremental false",
|
||||
"typecheck": "tsc6 --noEmit --incremental false",
|
||||
"biome:check": "biome check --write .",
|
||||
"biome:lint": "biome lint .",
|
||||
"biome:format": "biome format --write .",
|
||||
@@ -43,11 +43,11 @@
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@hookform/resolvers": "^5.4.0",
|
||||
"@prisma/adapter-mariadb": "^7.9.0",
|
||||
"@prisma/client": "^7.9.0",
|
||||
"@sentry/nextjs": "^10.67.0",
|
||||
"@tanstack/react-virtual": "^3.14.7",
|
||||
"@hookform/resolvers": "^5.5.7",
|
||||
"@prisma/adapter-mariadb": "^7.9.1",
|
||||
"@prisma/client": "^7.9.1",
|
||||
"@sentry/nextjs": "^10.68.0",
|
||||
"@tanstack/react-virtual": "^3.14.8",
|
||||
"bcrypt": "^6.0.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
@@ -60,21 +60,21 @@
|
||||
"json5": "^2.2.3",
|
||||
"jszip": "^3.10.1",
|
||||
"lenis": "^1.3.25",
|
||||
"lucide-react": "^1.25.0",
|
||||
"lucide-react": "^1.27.0",
|
||||
"lzma": "^2.3.2",
|
||||
"music-metadata": "^11.14.0",
|
||||
"mysql2": "^3.23.1",
|
||||
"next": "^16.2.11",
|
||||
"mysql2": "^3.23.2",
|
||||
"next": "^16.2.12",
|
||||
"next-auth": "5.0.0-beta.32",
|
||||
"next-intl": "^4.13.3",
|
||||
"next-intl": "^4.13.4",
|
||||
"next-view-transitions": "^0.3.5",
|
||||
"nodemailer": "^9.0.3",
|
||||
"otplib": "^13.4.1",
|
||||
"pino": "^10.3.1",
|
||||
"react": "^19.2.8",
|
||||
"react-dom": "^19.2.8",
|
||||
"react-hook-form": "^7.82.0",
|
||||
"resend": "^6.18.0",
|
||||
"react-hook-form": "^7.83.0",
|
||||
"resend": "^6.18.1",
|
||||
"sanitize-html": "^2.17.6",
|
||||
"server-only": "^0.0.1",
|
||||
"sharp": "^0.35.3",
|
||||
@@ -84,34 +84,38 @@
|
||||
"zod": "^4.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.5.5",
|
||||
"@biomejs/biome": "2.5.6",
|
||||
"@eslint/js": "10.0.1",
|
||||
"@lhci/cli": "^0.15.1",
|
||||
"@next/bundle-analyzer": "^16.2.11",
|
||||
"@playwright/test": "^1.61.1",
|
||||
"@next/bundle-analyzer": "^16.2.12",
|
||||
"@next/eslint-plugin-next": "^16.2.12",
|
||||
"@playwright/test": "1.62.0",
|
||||
"@tailwindcss/forms": "^0.5.11",
|
||||
"@tailwindcss/postcss": "^4.3.3",
|
||||
"@tailwindcss/typography": "^0.5.20",
|
||||
"@types/bcrypt": "^6.0.0",
|
||||
"@types/node": "^26.1.1",
|
||||
"@types/nodemailer": "^7.0.12",
|
||||
"@types/node": "^26.1.2",
|
||||
"@types/nodemailer": "^8.0.1",
|
||||
"@types/react": "^19.2.17",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/sanitize-html": "^2.16.1",
|
||||
"@vitest/coverage-v8": "^4.1.10",
|
||||
"dotenv": "^17.0.0",
|
||||
"eslint": "10.7.0",
|
||||
"@vitest/coverage-v8": "4.1.10",
|
||||
"babel-plugin-react-compiler": "^1.0.0",
|
||||
"dotenv": "^17.4.2",
|
||||
"eslint": "10.8.0",
|
||||
"eslint-plugin-react-hooks": "^7.1.1",
|
||||
"eslint-plugin-security": "^4.0.1",
|
||||
"eslint-plugin-unused-imports": "4.4.1",
|
||||
"husky": "^9.1.7",
|
||||
"knip": "^6.27.0",
|
||||
"knip": "^6.29.0",
|
||||
"pino-pretty": "^13.1.3",
|
||||
"postcss": "^8.5.21",
|
||||
"prisma": "^7.9.0",
|
||||
"postcss": "^8.5.24",
|
||||
"prisma": "^7.9.1",
|
||||
"tailwindcss": "^4.3.3",
|
||||
"tsx": "^4.23.1",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
||||
"typescript-eslint": "^8.65.0",
|
||||
"vite": "^8.1.5",
|
||||
"vitest": "^4.1.10"
|
||||
"vite": "8.1.5",
|
||||
"vitest": "4.1.10"
|
||||
}
|
||||
}
|
||||
Generated
+1580
-1501
File diff suppressed because it is too large.
Load diff
+30
-10
@@ -1,15 +1,35 @@
|
||||
onlyBuiltDependencies:
|
||||
- esbuild
|
||||
- prisma
|
||||
- "@prisma/client"
|
||||
- "@prisma/engines"
|
||||
- sharp
|
||||
- "@parcel/watcher"
|
||||
- "@swc/core"
|
||||
- "@sentry/cli"
|
||||
- bcrypt
|
||||
# pnpm-workspace.yaml
|
||||
|
||||
# pnpm v11 vervanger voor onlyBuiltDependencies
|
||||
allowBuilds:
|
||||
esbuild: true
|
||||
prisma: true
|
||||
"@prisma/client": true
|
||||
"@prisma/engines": true
|
||||
sharp: true
|
||||
"@parcel/watcher": true
|
||||
"@swc/core": true
|
||||
"@sentry/cli": true
|
||||
bcrypt: true
|
||||
|
||||
# Al jouw overrides netjes bij elkaar inclusief de nieuwe security patches
|
||||
overrides:
|
||||
glob: "^10.4.5"
|
||||
inflight: "npm:lru-cache@^10.2.2"
|
||||
rimraf: "^5.0.7"
|
||||
uuid: "^9.0.1"
|
||||
fast-uri: "^3.1.3"
|
||||
"@hono/node-server": "^1.19.13"
|
||||
postcss: "^8.5.19"
|
||||
# Dwingt alle diepe subdependencies (zoals lhci) naar de veilige tmp-versie
|
||||
tmp: "^0.2.6"
|
||||
# NIEUWE SECURITY PATCHES:
|
||||
sharp: "^0.35.3"
|
||||
brace-expansion: "^5.0.8"
|
||||
|
||||
# Zorgt voor een schone terminal zonder de Next-Auth / Nodemailer waarschuwing
|
||||
peerDependencyRules:
|
||||
allowedVersions:
|
||||
nodemailer: "9.0.3"
|
||||
ignoreMissing:
|
||||
- nodemailer
|
||||
+40
-114
@@ -1,116 +1,42 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:recommended",
|
||||
":pinAllExceptPeerDependencies",
|
||||
"helpers:disableTypesNodeMajor"
|
||||
],
|
||||
"labels": ["dependencies"],
|
||||
"rangeStrategy": "bump",
|
||||
"dependencyDashboard": true,
|
||||
"dependencyDashboardTitle": "Dependency Dashboard",
|
||||
"commitMessagePrefix": "chore(deps):",
|
||||
"commitMessageAction": "update",
|
||||
"schedule": ["at any time"],
|
||||
"timezone": "Europe/Amsterdam",
|
||||
"rebaseWhen": "conflicted",
|
||||
"prCreation": "immediate",
|
||||
"prConcurrentLimit": 5,
|
||||
"packageRules": [
|
||||
{
|
||||
"description": "Group Next.js core and tooling",
|
||||
"matchPackageNames": ["next", "@next/bundle-analyzer", "next-auth", "next-intl", "next-view-transitions"],
|
||||
"groupName": "Next.js",
|
||||
"groupSlug": "nextjs"
|
||||
},
|
||||
{
|
||||
"description": "Group Prisma packages",
|
||||
"matchPackageNames": ["prisma", "@prisma/client", "@prisma/adapter-mariadb"],
|
||||
"groupName": "Prisma",
|
||||
"groupSlug": "prisma"
|
||||
},
|
||||
{
|
||||
"description": "Group React core and types",
|
||||
"matchPackageNames": ["react", "react-dom", "@types/react", "@types/react-dom"],
|
||||
"groupName": "React",
|
||||
"groupSlug": "react"
|
||||
},
|
||||
{
|
||||
"description": "Group Tailwind CSS packages",
|
||||
"matchPackageNames": ["tailwindcss", "@tailwindcss/postcss", "@tailwindcss/forms", "@tailwindcss/typography", "tailwindcss-animate", "tailwind-merge"],
|
||||
"groupName": "Tailwind CSS",
|
||||
"groupSlug": "tailwind"
|
||||
},
|
||||
{
|
||||
"description": "Group DnD kit packages",
|
||||
"matchPackageNames": ["@dnd-kit/core", "@dnd-kit/sortable", "@dnd-kit/utilities"],
|
||||
"groupName": "DnD Kit",
|
||||
"groupSlug": "dnd-kit"
|
||||
},
|
||||
{
|
||||
"description": "Group Biome with ESLint tooling",
|
||||
"matchPackageNames": ["@biomejs/biome", "eslint", "@eslint/js", "eslint-plugin-unused-imports", "typescript-eslint"],
|
||||
"groupName": "Linting",
|
||||
"groupSlug": "linting"
|
||||
},
|
||||
{
|
||||
"description": "Group TypeScript and types",
|
||||
"matchPackageNames": ["typescript", "typescript-eslint"],
|
||||
"groupName": "TypeScript",
|
||||
"groupSlug": "typescript"
|
||||
},
|
||||
{
|
||||
"description": "Group Vitest and testing packages",
|
||||
"matchPackageNames": ["vitest", "@vitest/coverage-v8", "vite", "@playwright/test"],
|
||||
"groupName": "Testing",
|
||||
"groupSlug": "testing"
|
||||
},
|
||||
{
|
||||
"description": "Group Sentry packages",
|
||||
"matchPackageNames": ["@sentry/nextjs"],
|
||||
"groupName": "Sentry",
|
||||
"groupSlug": "sentry"
|
||||
},
|
||||
{
|
||||
"description": "Group hashing/crypto packages",
|
||||
"matchPackageNames": ["bcrypt", "@types/bcrypt", "hash-wasm", "otplib"],
|
||||
"groupName": "Cryptography",
|
||||
"groupSlug": "crypto"
|
||||
},
|
||||
{
|
||||
"description": "Group hook form packages",
|
||||
"matchPackageNames": ["react-hook-form", "@hookform/resolvers"],
|
||||
"groupName": "React Hook Form",
|
||||
"groupSlug": "react-hook-form"
|
||||
},
|
||||
{
|
||||
"description": "Automerge minor and patch updates for production deps (already >=1.0.0)",
|
||||
"matchUpdateTypes": ["minor", "patch"],
|
||||
"matchCurrentVersion": ">=1.0.0",
|
||||
"automerge": true
|
||||
},
|
||||
{
|
||||
"description": "Automerge all devDependency updates",
|
||||
"matchDepTypes": ["devDependencies"],
|
||||
"automerge": true
|
||||
},
|
||||
{
|
||||
"description": "Major updates need manual review",
|
||||
"matchUpdateTypes": ["major"],
|
||||
"labels": ["dependencies", "major"],
|
||||
"automerge": false,
|
||||
"assignees": [],
|
||||
"reviewers": []
|
||||
},
|
||||
{
|
||||
"description": "Disable updates for engine pins",
|
||||
"matchPackageNames": ["node", "pnpm"],
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"description": "Disable server-only (abandoned, pinned at 0.0.1)",
|
||||
"matchPackageNames": ["server-only"],
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["config:recommended", "helpers:disableTypesNodeMajor"],
|
||||
"labels": ["dependencies"],
|
||||
"rangeStrategy": "bump",
|
||||
"dependencyDashboard": true,
|
||||
"dependencyDashboardTitle": "Dependency Dashboard",
|
||||
"commitMessagePrefix": "chore(deps):",
|
||||
"commitMessageAction": "update",
|
||||
"schedule": ["at any time"],
|
||||
"timezone": "Europe/Amsterdam",
|
||||
"rebaseWhen": "conflicted",
|
||||
"prCreation": "immediate",
|
||||
"prConcurrentLimit": 5,
|
||||
"packageRules": [
|
||||
{
|
||||
"description": "Group all dependency updates into a single PR",
|
||||
"matchPackagePatterns": ["*"],
|
||||
"groupName": "All dependencies",
|
||||
"groupSlug": "all",
|
||||
"automerge": true
|
||||
},
|
||||
{
|
||||
"description": "Major updates need manual review",
|
||||
"matchUpdateTypes": ["major"],
|
||||
"labels": ["dependencies", "major"],
|
||||
"automerge": false,
|
||||
"assignees": [],
|
||||
"reviewers": []
|
||||
},
|
||||
{
|
||||
"description": "Disable updates for engine pins",
|
||||
"matchPackageNames": ["node", "pnpm"],
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"description": "Disable server-only (abandoned, pinned at 0.0.1)",
|
||||
"matchPackageNames": ["server-only"],
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -220,7 +220,7 @@ export function ClientView({
|
||||
window.removeEventListener("touchmove", onTouchMove);
|
||||
window.removeEventListener("touchend", onEnd);
|
||||
};
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: snapPos is a useCallback used intentionally here
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: snapPos is a useCallback used intentionally here
|
||||
}, [dragging, snapPos]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -144,7 +144,7 @@ export function InlineEditor({ pageId, onSaved }: InlineEditorProps) {
|
||||
}
|
||||
document.addEventListener("keydown", onKeyDown);
|
||||
return () => document.removeEventListener("keydown", onKeyDown);
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: handleSave is a stable callback from parent
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: handleSave is a stable callback from parent
|
||||
}, [canEdit, isDirty, saving, page, handleSave]);
|
||||
|
||||
const loadPage = useCallback(
|
||||
|
||||
@@ -338,13 +338,13 @@ export function RegisterForm({
|
||||
>
|
||||
{isPending ? (
|
||||
<span className="inline-flex items-center justify-center gap-2">
|
||||
<svg
|
||||
className="animate-spin h-4 w-4"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
role="img"
|
||||
aria-label="Loading"
|
||||
>
|
||||
<svg
|
||||
className="animate-spin h-4 w-4"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
role="img"
|
||||
aria-label="Loading"
|
||||
>
|
||||
<circle
|
||||
className="opacity-25"
|
||||
cx="12"
|
||||
|
||||
@@ -4,7 +4,11 @@ import type * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function Label({ className, htmlFor, ...props }: React.ComponentProps<"label">) {
|
||||
function Label({
|
||||
className,
|
||||
htmlFor,
|
||||
...props
|
||||
}: React.ComponentProps<"label">) {
|
||||
return (
|
||||
// biome-ignore lint/a11y/noLabelWithoutControl: reusable component, input is associated via htmlFor at usage site
|
||||
<label
|
||||
|
||||
@@ -34,8 +34,12 @@ describe("production deploy workflow", () => {
|
||||
const chownCmd = `sudo chown -R "${userVar}:${groupVar}"`;
|
||||
expect(toContainLiteral(workflow, chownCmd)).toBe(true);
|
||||
const reclaimAt = deployJob.indexOf(chownCmd);
|
||||
expect(toContainLiteral(deployJob, `git -C "${liveVar}" fetch origin --prune`)).toBe(true);
|
||||
const fetchAt = deployJob.indexOf(`git -C "${liveVar}" fetch origin --prune`);
|
||||
expect(
|
||||
toContainLiteral(deployJob, `git -C "${liveVar}" fetch origin --prune`),
|
||||
).toBe(true);
|
||||
const fetchAt = deployJob.indexOf(
|
||||
`git -C "${liveVar}" fetch origin --prune`,
|
||||
);
|
||||
expect(reclaimAt).toBeGreaterThan(-1);
|
||||
expect(fetchAt).toBeGreaterThan(reclaimAt);
|
||||
});
|
||||
@@ -53,8 +57,12 @@ describe("production deploy workflow", () => {
|
||||
|
||||
it("swaps a built .next artifact during a short service cutover", () => {
|
||||
expect(deployJob).toContain("mv .next .next.prev");
|
||||
expect(toContainLiteral(deployJob, `mv "${stageVar}/.next" .next`)).toBe(true);
|
||||
expect(toContainLiteral(deployJob, `mv "${stageVar}/node_modules" node_modules`)).toBe(true);
|
||||
expect(toContainLiteral(deployJob, `mv "${stageVar}/.next" .next`)).toBe(
|
||||
true,
|
||||
);
|
||||
expect(
|
||||
toContainLiteral(deployJob, `mv "${stageVar}/node_modules" node_modules`),
|
||||
).toBe(true);
|
||||
expect(deployJob).toContain("Rolling back .next to previous artifact");
|
||||
const buildAt = deployJob.indexOf("pnpm build");
|
||||
const stopAt = deployJob.indexOf("pm2 stop next");
|
||||
@@ -84,7 +92,12 @@ describe("production deploy workflow", () => {
|
||||
it("exports APP_VERSION from git for Sentry releases", () => {
|
||||
const exportCmd = `export APP_VERSION="$(git -C "${liveVar}" rev-parse --short origin/main)"`;
|
||||
expect(toContainLiteral(workflow, exportCmd)).toBe(true);
|
||||
expect(toContainLiteral(workflow, `export NEXT_PUBLIC_APP_VERSION="${appVerVar}"`)).toBe(true);
|
||||
expect(
|
||||
toContainLiteral(
|
||||
workflow,
|
||||
`export NEXT_PUBLIC_APP_VERSION="${appVerVar}"`,
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("runs an HTTP health check before declaring deploy success", () => {
|
||||
|
||||
@@ -9,10 +9,23 @@ const mockDb = {} as CurrencyDb;
|
||||
|
||||
describe("sendCurrency", () => {
|
||||
it("returns false for non-positive amount", async () => {
|
||||
expect(await sendCurrency({ rcon: {} as never, db: mockDb }, 1, "credits", 0)).toBe(false);
|
||||
expect(await sendCurrency({ rcon: {} as never, db: mockDb }, 1, "credits", -5)).toBe(false);
|
||||
expect(await sendCurrency({ rcon: {} as never, db: mockDb }, 1, "credits", null)).toBe(false);
|
||||
expect(await sendCurrency({ rcon: {} as never, db: mockDb }, 1, "credits", undefined)).toBe(false);
|
||||
expect(
|
||||
await sendCurrency({ rcon: {} as never, db: mockDb }, 1, "credits", 0),
|
||||
).toBe(false);
|
||||
expect(
|
||||
await sendCurrency({ rcon: {} as never, db: mockDb }, 1, "credits", -5),
|
||||
).toBe(false);
|
||||
expect(
|
||||
await sendCurrency({ rcon: {} as never, db: mockDb }, 1, "credits", null),
|
||||
).toBe(false);
|
||||
expect(
|
||||
await sendCurrency(
|
||||
{ rcon: {} as never, db: mockDb },
|
||||
1,
|
||||
"credits",
|
||||
undefined,
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("delivers credits via RCON", async () => {
|
||||
@@ -23,7 +36,10 @@ describe("sendCurrency", () => {
|
||||
givePointsGotw: vi.fn(),
|
||||
};
|
||||
const result = await sendCurrency(
|
||||
{ rcon, db: { user: { update: vi.fn() }, usersCurrency: { upsert: vi.fn() } } },
|
||||
{
|
||||
rcon,
|
||||
db: { user: { update: vi.fn() }, usersCurrency: { upsert: vi.fn() } },
|
||||
},
|
||||
1,
|
||||
"credits",
|
||||
100,
|
||||
@@ -43,7 +59,10 @@ describe("sendCurrency", () => {
|
||||
const result = await sendCurrency(
|
||||
{
|
||||
rcon,
|
||||
db: { user: { update: userUpdate }, usersCurrency: { upsert: vi.fn() } },
|
||||
db: {
|
||||
user: { update: userUpdate },
|
||||
usersCurrency: { upsert: vi.fn() },
|
||||
},
|
||||
},
|
||||
1,
|
||||
"credits",
|
||||
@@ -64,7 +83,10 @@ describe("sendCurrency", () => {
|
||||
givePointsGotw: vi.fn(),
|
||||
};
|
||||
const result = await sendCurrency(
|
||||
{ rcon, db: { user: { update: vi.fn() }, usersCurrency: { upsert: vi.fn() } } },
|
||||
{
|
||||
rcon,
|
||||
db: { user: { update: vi.fn() }, usersCurrency: { upsert: vi.fn() } },
|
||||
},
|
||||
1,
|
||||
"duckets",
|
||||
50,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
}
|
||||
],
|
||||
"baseUrl": ".",
|
||||
"ignoreDeprecations": "6.0",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user