* feat: group backlinks table by domain with expandable rows Group individual backlinks by source domain in the Backlinks tab, showing a compact domain summary row that expands to reveal individual backlink entries. Uses TanStack Table for expand/collapse state management with table-fixed layout for stable column widths. * fix: ci:check fixes for grouped backlinks table Extract BacklinkChildRow to its own file to stay under max-lines lint rule. Remove unused export of sortBacklinkRows. Format files with prettier. * refactor: simplify grouped backlinks table * refactor: split backlinks page tables into focused files Break the backlinks, referring domains, and top pages tables into dedicated components so the feature stays easier to navigate and no longer needs a max-lines ignore. * fix: correct grouped backlink totals and remove target sorting * fix: stabilize backlinks table column layout Keep the DA header aligned with numeric cells and lock the backlinks table to fixed column widths so expanded rows with long anchor text do not shift the layout. * refactor: inline backlinks table imports
106 lines
3.8 KiB
JSON
106 lines
3.8 KiB
JSON
{
|
|
"name": "open-seo",
|
|
"private": true,
|
|
"sideEffects": false,
|
|
"version": "0.0.4",
|
|
"type": "module",
|
|
"scripts": {
|
|
"dev": "AUTH_MODE=local_noauth vite dev",
|
|
"dev:agents": "mkdir -p .logs && portless run vite dev 2>&1 | tee .logs/dev-server.log",
|
|
"dev:agents:force": "mkdir -p .logs && portless --force run vite dev 2>&1 | tee .logs/dev-server.log",
|
|
"build": "vite build && tsc --noEmit",
|
|
"lint": "oxlint . --type-aware",
|
|
"lint:fix": "oxlint . --type-aware --fix",
|
|
"preview": "npm run build && vite preview --port 3001",
|
|
"deploy": "npm run db:migrate:prod && npm run build && wrangler deploy",
|
|
"cf-typegen": "wrangler types",
|
|
"types:check": "tsc --noEmit",
|
|
"format:check": "prettier --check .",
|
|
"format:write": "prettier . --write",
|
|
"auth:generate": "pnpm dlx auth@latest generate --config ./cli-auth.ts --adapter drizzle --dialect sqlite --output ./src/db/better-auth-schema.ts",
|
|
"db:generate": "drizzle-kit generate",
|
|
"db:migrate:local": "wrangler d1 migrations apply DB --local",
|
|
"db:migrate:prod": "wrangler d1 migrations apply DB --remote",
|
|
"knip": "knip",
|
|
"release:notes": "node scripts/release-notes.mjs",
|
|
"test": "vitest run",
|
|
"test:watch": "vitest",
|
|
"test:ci": "vitest run --reporter=dot",
|
|
"billing:backlinks": "tsx scripts/backlinks-cost-profile.ts",
|
|
"ci:check": "prettier --check . && knip && tsc --noEmit && oxlint . --type-aware"
|
|
},
|
|
"cloudflare": {
|
|
"bindings": {
|
|
"AUTH_MODE": {
|
|
"description": "Set to `cloudflare_access` for secured deployments behind Cloudflare Access, or `local_noauth` for trusted local self-host mode only."
|
|
},
|
|
"TEAM_DOMAIN": {
|
|
"description": "Cloudflare Access team domain (for example `https://your-team.cloudflareaccess.com`) used to validate `cf-access-jwt-assertion` JWTs."
|
|
},
|
|
"POLICY_AUD": {
|
|
"description": "Cloudflare Access Application Audience (AUD) tag for this Worker route/domain."
|
|
},
|
|
"DATAFORSEO_API_KEY": {
|
|
"description": "Base64-encoded `login:password` for DataForSEO API access."
|
|
}
|
|
}
|
|
},
|
|
"dependencies": {
|
|
"@every-app/sdk": "^0.1.14",
|
|
"@tanstack/query-core": "^5.90.9",
|
|
"@tanstack/react-form": "^1.25.0",
|
|
"@tanstack/react-query": "^5.90.9",
|
|
"@tanstack/react-router": "^1.136.3",
|
|
"@tanstack/react-router-devtools": "^1.136.3",
|
|
"@tanstack/react-start": "^1.136.3",
|
|
"@tanstack/react-table": "^8.21.3",
|
|
"autumn-js": "^1.1.7",
|
|
"better-auth": "^1.5.5",
|
|
"cheerio": "^1.2.0",
|
|
"cloudflare": "^5.2.0",
|
|
"daisyui": "^5.5.5",
|
|
"dataforseo-client": "^2.0.19",
|
|
"drizzle-orm": "^0.44.4",
|
|
"fast-xml-parser": "^5.4.1",
|
|
"jose": "^6.0.12",
|
|
"lucide-react": "^0.542.0",
|
|
"papaparse": "^5.5.3",
|
|
"posthog-js": "^1.363.5",
|
|
"posthog-node": "^5.28.5",
|
|
"react": "^19.0.0",
|
|
"react-dom": "^19.0.0",
|
|
"recharts": "^3.7.0",
|
|
"remeda": "^2.33.6",
|
|
"robots-parser": "^3.0.1",
|
|
"sonner": "^2.0.7",
|
|
"tailwindcss": "^4.1.16",
|
|
"tldts": "^7.0.25",
|
|
"zod": "^4.1.12"
|
|
},
|
|
"devDependencies": {
|
|
"@cloudflare/vite-plugin": "^1.13.18",
|
|
"@cloudflare/workers-types": "^4.20251014.0",
|
|
"@libsql/client": "^0.15.15",
|
|
"@tailwindcss/vite": "^4.1.11",
|
|
"@tanstack/devtools-vite": "^0.5.1",
|
|
"@tanstack/react-devtools": "^0.9.6",
|
|
"@types/node": "^22.18.13",
|
|
"@types/papaparse": "^5.5.2",
|
|
"@types/react": "^19.0.8",
|
|
"@types/react-dom": "^19.0.3",
|
|
"@vitejs/plugin-react": "^4.6.0",
|
|
"drizzle-kit": "^0.31.4",
|
|
"knip": "^5.66.4",
|
|
"oxlint": "^1.50.0",
|
|
"oxlint-tsgolint": "^0.15.0",
|
|
"portless": "^0.5.2",
|
|
"prettier": "^3.6.2",
|
|
"tsx": "^4.21.0",
|
|
"typescript": "^5.9.3",
|
|
"vite": "^7.1.2",
|
|
"vite-tsconfig-paths": "^5.1.4",
|
|
"vitest": "^3.2.4",
|
|
"wrangler": "^4.45.3"
|
|
}
|
|
}
|