chore(workspace): streamline monorepo and CI with pnpm workspace, dependency, and workflow updates

Update GitHub Actions workflows to latest action versions and improve pnpm usage by introducing per-package workspace configs. Add docs-site/pnpm-workspace.yaml and update Dockerfile/package.json for better monorepo support. Upgrade dependencies across main and docs-site packages for compatibility and security. Refine TypeScript types and hooks for improved type safety and maintainability.
This commit is contained in:
Richard R 2026-05-14 15:44:22 -06:00
parent 288af0f370
commit 64182e6c8d
15 changed files with 2225 additions and 1856 deletions

View file

@ -36,7 +36,7 @@ jobs:
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: |
${{ env.REGISTRY }}/${{ steps.image-name.outputs.image_name }}
@ -67,16 +67,16 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
ref: ${{ github.sha }}
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
@ -84,7 +84,7 @@ jobs:
- name: Build and push Docker image (${{ matrix.arch }})
id: build
uses: docker/build-push-action@v5
uses: docker/build-push-action@v7
with:
context: .
platforms: ${{ matrix.platform }}
@ -101,7 +101,7 @@ jobs:
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: digests-${{ matrix.arch }}
path: /tmp/digests
@ -118,17 +118,17 @@ jobs:
steps:
- name: Download digests
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}

View file

@ -16,22 +16,22 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 11
uses: pnpm/action-setup@v6
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: 20
node-version: lts/*
cache: pnpm
cache-dependency-path: docs-site/pnpm-lock.yaml
- name: Install docs dependencies
run: pnpm --ignore-workspace --dir docs-site install --frozen-lockfile
working-directory: docs-site
run: pnpm install --frozen-lockfile
- name: Build docs
run: pnpm --ignore-workspace --dir docs-site build
working-directory: docs-site
run: pnpm build

View file

@ -32,24 +32,23 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
ref: main
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 11
uses: pnpm/action-setup@v6
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: 20
node-version: lts/*
cache: pnpm
cache-dependency-path: docs-site/pnpm-lock.yaml
- name: Install docs dependencies
run: pnpm --ignore-workspace --dir docs-site install --frozen-lockfile
working-directory: docs-site
run: pnpm install --frozen-lockfile
- name: Build changelog feed
env:
@ -59,10 +58,11 @@ jobs:
run: node scripts/build-changelog-feed.mjs
- name: Build docs
run: pnpm --ignore-workspace --dir docs-site build
working-directory: docs-site
run: pnpm build
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
uses: actions/upload-pages-artifact@v5
with:
path: docs-site/build
@ -76,4 +76,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v5

View file

@ -24,39 +24,40 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.source_ref || github.sha }}
fetch-depth: 0
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 11
uses: pnpm/action-setup@v6
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: 20
node-version: lts/*
cache: pnpm
cache-dependency-path: docs-site/pnpm-lock.yaml
- name: Install docs dependencies
run: pnpm --ignore-workspace --dir docs-site install --frozen-lockfile
working-directory: docs-site
run: pnpm install --frozen-lockfile
- name: Snapshot docs version
working-directory: docs-site
env:
VERSION: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version || github.ref_name }}
run: |
set -euo pipefail
if [ -f docs-site/versions.json ] && grep -q "\"${VERSION}\"" docs-site/versions.json; then
if [ -f versions.json ] && grep -q "\"${VERSION}\"" versions.json; then
echo "Version ${VERSION} already exists in versions.json; skipping docs:version"
else
pnpm --ignore-workspace --dir docs-site docusaurus docs:version "${VERSION}"
pnpm docusaurus docs:version "${VERSION}"
fi
- name: Build docs
run: pnpm --ignore-workspace --dir docs-site build
working-directory: docs-site
run: pnpm build
- name: Commit docs snapshot
id: commit_snapshot

View file

@ -4,6 +4,7 @@ on:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
e2e-testing:
timeout-minutes: 60
@ -14,13 +15,12 @@ jobs:
BASE_URL: http://127.0.0.1:3003
S3_ENDPOINT: http://127.0.0.1:8333
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: lts/*
- uses: pnpm/action-setup@v4
with:
version: 11
package-manager-cache: false
- uses: pnpm/action-setup@v6
- name: Install system dependencies
run: |
sudo apt-get update
@ -45,7 +45,7 @@ jobs:
API_BASE: https://api.deepinfra.com/v1/openai
API_KEY: ${{ secrets.DEEPINFRA_API_KEY }}
run: pnpm exec playwright test --reporter=list,github,html
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
if: ${{ !cancelled() }}
with:
name: playwright-report

View file

@ -30,7 +30,7 @@ RUN npm install -g pnpm@11.1.2
WORKDIR /app
# Copy package files
COPY package.json pnpm-lock.yaml ./
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
# Install dependencies
RUN pnpm install --frozen-lockfile

View file

@ -12,6 +12,7 @@
"deploy": "docusaurus deploy"
},
"dependencies": {
"@mdx-js/react": "^3.1.1",
"@docusaurus/core": "^3.9.2",
"@docusaurus/preset-classic": "^3.9.2",
"@easyops-cn/docusaurus-search-local": "^0.54.1",

View file

@ -17,6 +17,9 @@ importers:
'@easyops-cn/docusaurus-search-local':
specifier: ^0.54.1
version: 0.54.1(@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.13)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.1.1(@types/react@19.2.13)(react@18.3.1))(@types/react@19.2.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)
'@mdx-js/react':
specifier: ^3.1.1
version: 3.1.1(@types/react@19.2.13)(react@18.3.1)
clsx:
specifier: ^2.1.1
version: 2.1.1
@ -1433,24 +1436,28 @@ packages:
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@node-rs/jieba-linux-arm64-musl@1.10.4':
resolution: {integrity: sha512-Y/tiJ1+HeS5nnmLbZOE+66LbsPOHZ/PUckAYVeLlQfpygLEpLYdlh0aPpS5uiaWMjAXYZYdFkpZHhxDmSLpwpw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@node-rs/jieba-linux-x64-gnu@1.10.4':
resolution: {integrity: sha512-WZO8ykRJpWGE9MHuZpy1lu3nJluPoeB+fIJJn5CWZ9YTVhNDWoCF4i/7nxz1ntulINYGQ8VVuCU9LD86Mek97g==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@node-rs/jieba-linux-x64-musl@1.10.4':
resolution: {integrity: sha512-uBBD4S1rGKcgCyAk6VCKatEVQb6EDD5I40v/DxODi5CuZVCANi9m5oee/MQbAoaX7RydA2f0OSCE9/tcwXEwUg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [musl]
'@node-rs/jieba-wasm32-wasi@1.10.4':
resolution: {integrity: sha512-Y2umiKHjuIJy0uulNDz9SDYHdfq5Hmy7jY5nORO99B4pySKkcrMjpeVrmWXJLIsEKLJwcCXHxz8tjwU5/uhz0A==}
@ -2006,6 +2013,7 @@ packages:
'@ungap/structured-clone@1.3.0':
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
deprecated: Potential CWE-502 - Update to 1.3.1 or higher
'@webassemblyjs/ast@1.14.1':
resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==}
@ -5356,6 +5364,7 @@ packages:
uuid@8.3.2:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).
hasBin: true
value-equal@1.0.1:

View file

@ -0,0 +1,6 @@
packages:
- .
allowBuilds:
core-js: true
core-js-pure: true

View file

@ -15,46 +15,46 @@
"migrate-fs": "node scripts/migrate-fs-v2.mjs",
"migrate-fs:dry-run": "node scripts/migrate-fs-v2.mjs --dry-run true",
"generate": "node drizzle/scripts/generate.mjs",
"docs:init": "pnpm --ignore-workspace --dir docs-site install",
"docs:dev": "pnpm --ignore-workspace --dir docs-site start",
"docs:build": "pnpm --ignore-workspace --dir docs-site build",
"docs:serve": "pnpm --ignore-workspace --dir docs-site serve",
"docs:version": "pnpm --ignore-workspace --dir docs-site docusaurus docs:version",
"docs:clear": "pnpm --ignore-workspace --dir docs-site clear"
"docs:init": "pnpm --dir docs-site install",
"docs:dev": "pnpm --dir docs-site start",
"docs:build": "pnpm --dir docs-site build",
"docs:serve": "pnpm --dir docs-site serve",
"docs:version": "pnpm --dir docs-site docusaurus docs:version",
"docs:clear": "pnpm --dir docs-site clear"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.987.0",
"@aws-sdk/s3-request-presigner": "^3.987.0",
"@headlessui/react": "^2.2.9",
"@napi-rs/canvas": "^0.1.91",
"@aws-sdk/client-s3": "^3.1045.0",
"@aws-sdk/s3-request-presigner": "^3.1045.0",
"@headlessui/react": "^2.2.10",
"@napi-rs/canvas": "^0.1.100",
"@tanstack/react-query": "^5.100.10",
"@types/archiver": "^7.0.0",
"@vercel/analytics": "^1.6.1",
"archiver": "^7.0.1",
"better-auth": "^1.4.18",
"better-sqlite3": "^12.6.2",
"cmpstr": "^3.2.1",
"compromise": "^14.14.5",
"core-js": "^3.48.0",
"dexie": "^4.3.0",
"dexie-react-hooks": "^4.2.0",
"dotenv": "^17.2.4",
"drizzle-kit": "^0.31.9",
"drizzle-orm": "^0.45.1",
"better-auth": "^1.6.11",
"better-sqlite3": "^12.10.0",
"cmpstr": "^3.3.0",
"compromise": "^14.15.0",
"core-js": "^3.49.0",
"dexie": "^4.4.2",
"dexie-react-hooks": "^4.4.0",
"dotenv": "^17.4.2",
"drizzle-kit": "^0.31.10",
"drizzle-orm": "^0.45.2",
"epubjs": "^0.3.93",
"fast-xml-parser": "^5.3.5",
"fast-xml-parser": "^5.8.0",
"ffmpeg-static": "^5.3.0",
"howler": "^2.2.4",
"jszip": "^3.10.1",
"lru-cache": "^11.2.6",
"next": "^15.5.12",
"openai": "^6.21.0",
"lru-cache": "^11.3.6",
"next": "^15.5.18",
"openai": "^6.37.0",
"pdfjs-dist": "4.8.69",
"pg": "^8.18.0",
"react": "^19.2.4",
"pg": "^8.20.0",
"react": "^19.2.6",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "^19.2.4",
"react-dom": "^19.2.6",
"react-dropzone": "^14.4.1",
"react-hot-toast": "^2.6.0",
"react-markdown": "^10.1.0",
@ -62,22 +62,22 @@
"react-reader": "^2.0.15",
"remark-gfm": "^4.0.1",
"replicate": "^1.4.0",
"uuid": "^11.1.0"
"uuid": "^11.1.1"
},
"devDependencies": {
"@eslint/eslintrc": "^3.3.3",
"@playwright/test": "^1.58.2",
"@eslint/eslintrc": "^3.3.5",
"@playwright/test": "^1.60.0",
"@tailwindcss/typography": "^0.5.19",
"@types/better-sqlite3": "^7.6.13",
"@types/howler": "^2.2.12",
"@types/node": "^20.19.33",
"@types/pg": "^8.16.0",
"@types/react": "^19.2.13",
"@types/node": "^20.19.41",
"@types/pg": "^8.20.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@types/uuid": "^10.0.0",
"eslint": "^9.39.2",
"eslint-config-next": "^15.5.12",
"postcss": "^8.5.6",
"eslint": "^9.39.4",
"eslint-config-next": "^15.5.18",
"postcss": "^8.5.14",
"tailwindcss": "^3.4.19",
"typescript": "^5.9.3"
}

File diff suppressed because it is too large Load diff

View file

@ -52,7 +52,7 @@ export async function GET(req: NextRequest) {
});
}
const isAnonymous = Boolean(session.user.isAnonymous);
const isAnonymous = Boolean((session.user as { isAnonymous?: boolean }).isAnonymous);
const ip = getClientIp(req);
const device = isTtsRateLimitEnabled() ? (isAnonymous ? getOrCreateDeviceId(req) : null) : null;

View file

@ -167,7 +167,7 @@ export function useEPUBHighlighting({
const setRenderedTextMaps = useCallback((maps: EpubRenderedTextMap[]) => {
renderedTextMapsRef.current = maps;
wordHighlightMapCacheRef.current = null;
}, []);
}, [renderedTextMapsRef, wordHighlightMapCacheRef]);
const resetHighlightState = useCallback(() => {
renderedTextMapsRef.current = [];

View file

@ -159,10 +159,12 @@ export function useEPUBLocationController({
bookRef,
documentId,
extractPageText,
isEpubSetOnceRef,
locationRef,
renditionRef,
safeRenditionNavigate,
setIsEpub,
shouldPauseRef,
skipToLocation,
]);

View file

@ -226,7 +226,10 @@ export const auth = isAuthEnabled() ? createAuth() : null;
type AuthInstance = ReturnType<typeof createAuth>;
export type Session = AuthInstance["$Infer"]["Session"];
export type User = AuthInstance["$Infer"]["Session"]["user"];
type AuthSessionUser = AuthInstance["$Infer"]["Session"]["user"];
export type User = AuthSessionUser & {
isAnonymous?: boolean;
};
export type AuthContext = {
authEnabled: boolean;
@ -243,7 +246,7 @@ export async function getAuthContext(request: Pick<NextRequest, 'headers'>): Pro
}
const session = await auth.api.getSession({ headers: request.headers });
const user = session?.user ?? null;
const user = (session?.user ?? null) as User | null;
const userId = user?.id ?? null;
// Keep user.isAdmin in sync with ADMIN_EMAILS on every session resolution.