mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-11-16 01:21:16 +01:00
Update PDF.js integration and dependencies (#4360)
Co-authored-by: ConnorYoh <40631091+ConnorYoh@users.noreply.github.com> Co-authored-by: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
This commit is contained in:
parent
13eff6b333
commit
25bedf064f
158
.github/workflows/PR-Auto-Deploy-V2.yml
vendored
158
.github/workflows/PR-Auto-Deploy-V2.yml
vendored
@ -3,7 +3,15 @@ name: Auto PR V2 Deployment
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [opened, synchronize, reopened, closed]
|
types: [opened, synchronize, reopened, closed]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
pr:
|
||||||
|
description: "PR number to deploy"
|
||||||
|
required: true
|
||||||
|
allow_fork:
|
||||||
|
description: "Allow deploying fork PR?"
|
||||||
|
required: false
|
||||||
|
default: "false"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@ -12,102 +20,93 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-pr:
|
check-pr:
|
||||||
if: github.event.action != 'closed'
|
if: (github.event_name == 'pull_request' && github.event.action != 'closed') || github.event_name == 'workflow_dispatch'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
should_deploy: ${{ steps.check-conditions.outputs.should_deploy }}
|
should_deploy: ${{ steps.decide.outputs.should_deploy }}
|
||||||
pr_number: ${{ github.event.number }}
|
is_fork: ${{ steps.resolve.outputs.is_fork }}
|
||||||
pr_repository: ${{ steps.get-pr-info.outputs.repository }}
|
allow_fork: ${{ steps.decide.outputs.allow_fork }}
|
||||||
pr_ref: ${{ steps.get-pr-info.outputs.ref }}
|
pr_number: ${{ steps.resolve.outputs.pr_number }}
|
||||||
|
pr_repository: ${{ steps.resolve.outputs.repository }}
|
||||||
|
pr_ref: ${{ steps.resolve.outputs.ref }}
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
|
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Check deployment conditions
|
- name: Resolve PR info
|
||||||
id: check-conditions
|
id: resolve
|
||||||
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { owner, repo } = context.repo;
|
||||||
|
let prNumber = context.eventName === 'workflow_dispatch'
|
||||||
|
? parseInt(process.env.INPUT_PR, 10)
|
||||||
|
: context.payload.number;
|
||||||
|
|
||||||
|
if (!Number.isInteger(prNumber)) { core.setFailed('Invalid PR number'); return; }
|
||||||
|
|
||||||
|
const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number: prNumber });
|
||||||
|
core.setOutput('pr_number', String(prNumber));
|
||||||
|
core.setOutput('repository', pr.head.repo.full_name);
|
||||||
|
core.setOutput('ref', pr.head.ref);
|
||||||
|
core.setOutput('is_fork', String(pr.head.repo.fork));
|
||||||
|
core.setOutput('base_ref', pr.base.ref);
|
||||||
|
core.setOutput('author', pr.user.login);
|
||||||
|
core.setOutput('state', pr.state);
|
||||||
|
|
||||||
|
- name: Decide deploy
|
||||||
|
id: decide
|
||||||
|
shell: bash
|
||||||
env:
|
env:
|
||||||
|
EVENT_NAME: ${{ github.event_name }}
|
||||||
|
STATE: ${{ steps.resolve.outputs.state }}
|
||||||
|
IS_FORK: ${{ steps.resolve.outputs.is_fork }}
|
||||||
|
# nur bei workflow_dispatch gesetzt:
|
||||||
|
ALLOW_FORK_INPUT: ${{ inputs.allow_fork }}
|
||||||
|
# für Auto-PR-Logik:
|
||||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||||
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
|
|
||||||
PR_BRANCH: ${{ github.event.pull_request.head.ref }}
|
PR_BRANCH: ${{ github.event.pull_request.head.ref }}
|
||||||
|
PR_BASE: ${{ steps.resolve.outputs.base_ref }}
|
||||||
|
PR_AUTHOR: ${{ steps.resolve.outputs.author }}
|
||||||
run: |
|
run: |
|
||||||
echo "PR Title: $PR_TITLE"
|
set -e
|
||||||
echo "PR Author: $PR_AUTHOR"
|
# Standard: nichts deployen
|
||||||
echo "PR Branch: $PR_BRANCH"
|
should=false
|
||||||
echo "PR Base Branch: ${{ github.event.pull_request.base.ref }}"
|
allow_fork="$(echo "${ALLOW_FORK_INPUT:-false}" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
|
||||||
# Define authorized users
|
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
|
||||||
authorized_users=(
|
if [ "$STATE" != "open" ]; then
|
||||||
"Frooodle"
|
echo "PR not open -> skip"
|
||||||
"sf298"
|
|
||||||
"Ludy87"
|
|
||||||
"LaserKaspar"
|
|
||||||
"sbplat"
|
|
||||||
"reecebrowne"
|
|
||||||
"DarioGii"
|
|
||||||
"ConnorYoh"
|
|
||||||
"EthanHealy01"
|
|
||||||
"jbrunton96"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check if author is in the authorized list
|
|
||||||
is_authorized=false
|
|
||||||
for user in "${authorized_users[@]}"; do
|
|
||||||
if [[ "$PR_AUTHOR" == "$user" ]]; then
|
|
||||||
is_authorized=true
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# If PR is targeting V2 and user is authorized, deploy unconditionally
|
|
||||||
PR_BASE_BRANCH="${{ github.event.pull_request.base.ref }}"
|
|
||||||
if [[ "$PR_BASE_BRANCH" == "V2" && "$is_authorized" == "true" ]]; then
|
|
||||||
echo "✅ Deployment forced: PR targets V2 and author is authorized."
|
|
||||||
echo "should_deploy=true" >> $GITHUB_OUTPUT
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Otherwise, continue with original keyword checks
|
|
||||||
has_v2_keyword=false
|
|
||||||
if [[ "$PR_TITLE" =~ [Vv]2 ]] || [[ "$PR_TITLE" =~ [Vv]ersion.?2 ]] || [[ "$PR_TITLE" =~ [Vv]ersion.?[Tt]wo ]]; then
|
|
||||||
has_v2_keyword=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
has_branch_keyword=false
|
|
||||||
if [[ "$PR_BRANCH" =~ [Vv]2 ]] || [[ "$PR_BRANCH" =~ [Rr]eact ]]; then
|
|
||||||
has_branch_keyword=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$is_authorized" == "true" && ( "$has_v2_keyword" == "true" || "$has_branch_keyword" == "true" ) ]]; then
|
|
||||||
echo "✅ Deployment conditions met"
|
|
||||||
echo "should_deploy=true" >> $GITHUB_OUTPUT
|
|
||||||
else
|
else
|
||||||
echo "❌ Deployment conditions not met"
|
if [ "$IS_FORK" = "true" ] && [ "$allow_fork" != "true" ]; then
|
||||||
echo " - Authorized user: $is_authorized"
|
echo "Fork PR and allow_fork=false -> skip"
|
||||||
echo " - Has V2 keyword in title: $has_v2_keyword"
|
|
||||||
echo " - Has V2/React keyword in branch: $has_branch_keyword"
|
|
||||||
echo "should_deploy=false" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Get PR repository and ref
|
|
||||||
id: get-pr-info
|
|
||||||
if: steps.check-conditions.outputs.should_deploy == 'true'
|
|
||||||
run: |
|
|
||||||
# For forks, use the full repository name, for internal PRs use the current repo
|
|
||||||
if [[ "${{ github.event.pull_request.head.repo.fork }}" == "true" ]]; then
|
|
||||||
repository="${{ github.event.pull_request.head.repo.full_name }}"
|
|
||||||
else
|
else
|
||||||
repository="${{ github.repository }}"
|
should=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
auth_users=("Frooodle" "sf298" "Ludy87" "LaserKaspar" "sbplat" "reecebrowne" "DarioGii" "ConnorYoh" "EthanHealy01" "jbrunton96")
|
||||||
|
is_auth=false; for u in "${auth_users[@]}"; do [ "$u" = "$PR_AUTHOR" ] && is_auth=true && break; done
|
||||||
|
if [ "$PR_BASE" = "V2" ] && [ "$is_auth" = true ]; then
|
||||||
|
should=true
|
||||||
|
else
|
||||||
|
title_has_v2=false; echo "$PR_TITLE" | grep -qiE 'v2|version.?2|version.?two' && title_has_v2=true
|
||||||
|
branch_has_kw=false; echo "$PR_BRANCH" | grep -qiE 'v2|react' && branch_has_kw=true
|
||||||
|
if [ "$is_auth" = true ] && { [ "$title_has_v2" = true ] || [ "$branch_has_kw" = true ]; }; then
|
||||||
|
should=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "repository=$repository" >> $GITHUB_OUTPUT
|
echo "should_deploy=$should" >> $GITHUB_OUTPUT
|
||||||
echo "ref=${{ github.event.pull_request.head.ref }}" >> $GITHUB_OUTPUT
|
echo "allow_fork=${allow_fork:-false}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
deploy-v2-pr:
|
deploy-v2-pr:
|
||||||
needs: check-pr
|
needs: check-pr
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: needs.check-pr.outputs.should_deploy == 'true'
|
if: needs.check-pr.outputs.should_deploy == 'true' && (needs.check-pr.outputs.is_fork == 'false' || needs.check-pr.outputs.allow_fork == 'true')
|
||||||
# Concurrency control - only one deployment per PR at a time
|
# Concurrency control - only one deployment per PR at a time
|
||||||
concurrency:
|
concurrency:
|
||||||
group: v2-deploy-pr-${{ needs.check-pr.outputs.pr_number }}
|
group: v2-deploy-pr-${{ needs.check-pr.outputs.pr_number }}
|
||||||
@ -119,7 +118,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
|
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@ -177,7 +176,6 @@ jobs:
|
|||||||
issue_number: prNumber,
|
issue_number: prNumber,
|
||||||
body: `🚀 **Auto-deploying V2 version** for PR #${prNumber}...\n\n_This is an automated deployment triggered by V2/version2 keywords in the PR title or V2/React keywords in the branch name._\n\n⚠️ **Note:** If new commits are pushed during deployment, this build will be cancelled and replaced with the latest version.`
|
body: `🚀 **Auto-deploying V2 version** for PR #${prNumber}...\n\n_This is an automated deployment triggered by V2/version2 keywords in the PR title or V2/React keywords in the branch name._\n\n⚠️ **Note:** If new commits are pushed during deployment, this build will be cancelled and replaced with the latest version.`
|
||||||
});
|
});
|
||||||
|
|
||||||
return newComment.id;
|
return newComment.id;
|
||||||
|
|
||||||
- name: Checkout PR
|
- name: Checkout PR
|
||||||
@ -188,7 +186,6 @@ jobs:
|
|||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
fetch-depth: 0 # Fetch full history for commit hash detection
|
fetch-depth: 0 # Fetch full history for commit hash detection
|
||||||
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
|
|
||||||
@ -502,4 +499,3 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
rm -f ../private.key
|
rm -f ../private.key
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
|
|||||||
74
.github/workflows/frontend-licenses-update.yml
vendored
74
.github/workflows/frontend-licenses-update.yml
vendored
@ -32,18 +32,29 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Check out code
|
- name: Checkout PR head (default)
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Setup GitHub App Bot
|
- name: Setup GitHub App Bot
|
||||||
|
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false)
|
||||||
id: setup-bot
|
id: setup-bot
|
||||||
uses: ./.github/actions/setup-bot
|
uses: ./.github/actions/setup-bot
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.GH_APP_ID }}
|
app-id: ${{ secrets.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
|
|
||||||
|
- name: Checkout BASE branch (safe script)
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.base.sha }}
|
||||||
|
path: base
|
||||||
|
fetch-depth: 1
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||||
with:
|
with:
|
||||||
@ -53,12 +64,45 @@ jobs:
|
|||||||
|
|
||||||
- name: Install frontend dependencies
|
- name: Install frontend dependencies
|
||||||
working-directory: frontend
|
working-directory: frontend
|
||||||
run: npm ci
|
env:
|
||||||
|
NPM_CONFIG_IGNORE_SCRIPTS: "true"
|
||||||
|
run: npm ci --ignore-scripts --audit=false --fund=false
|
||||||
|
|
||||||
- name: Generate frontend license report
|
- name: Generate frontend license report (internal PR)
|
||||||
|
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false
|
||||||
working-directory: frontend
|
working-directory: frontend
|
||||||
|
env:
|
||||||
|
PR_IS_FORK: "false"
|
||||||
run: npm run generate-licenses
|
run: npm run generate-licenses
|
||||||
|
|
||||||
|
- name: Generate frontend license report (fork PRs, pinned)
|
||||||
|
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true
|
||||||
|
env:
|
||||||
|
NPM_CONFIG_IGNORE_SCRIPTS: "true"
|
||||||
|
working-directory: frontend
|
||||||
|
run: |
|
||||||
|
mkdir -p src/assets
|
||||||
|
npx --yes license-report --only=prod --output=json > src/assets/3rdPartyLicenses.json
|
||||||
|
|
||||||
|
- name: Postprocess with project script (BASE version)
|
||||||
|
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true
|
||||||
|
env:
|
||||||
|
PR_IS_FORK: "true"
|
||||||
|
run: |
|
||||||
|
node base/frontend/scripts/generate-licenses.js \
|
||||||
|
--input frontend/src/assets/3rdPartyLicenses.json
|
||||||
|
|
||||||
|
- name: Copy postprocessed artifacts back (fork PRs)
|
||||||
|
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true
|
||||||
|
run: |
|
||||||
|
mkdir -p frontend/src/assets
|
||||||
|
if [ -f "base/frontend/src/assets/3rdPartyLicenses.json" ]; then
|
||||||
|
cp base/frontend/src/assets/3rdPartyLicenses.json frontend/src/assets/3rdPartyLicenses.json
|
||||||
|
fi
|
||||||
|
if [ -f "base/frontend/src/assets/license-warnings.json" ]; then
|
||||||
|
cp base/frontend/src/assets/license-warnings.json frontend/src/assets/license-warnings.json
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Check for license warnings
|
- name: Check for license warnings
|
||||||
run: |
|
run: |
|
||||||
if [ -f "frontend/src/assets/license-warnings.json" ]; then
|
if [ -f "frontend/src/assets/license-warnings.json" ]; then
|
||||||
@ -69,7 +113,7 @@ jobs:
|
|||||||
|
|
||||||
# PR Event: Check licenses and comment on PR
|
# PR Event: Check licenses and comment on PR
|
||||||
- name: Delete previous license check comments
|
- name: Delete previous license check comments
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||||
with:
|
with:
|
||||||
github-token: ${{ steps.setup-bot.outputs.token }}
|
github-token: ${{ steps.setup-bot.outputs.token }}
|
||||||
@ -101,8 +145,28 @@ jobs:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- name: Summarize results (fork PRs)
|
||||||
|
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true
|
||||||
|
run: |
|
||||||
|
{
|
||||||
|
echo "## Frontend License Check"
|
||||||
|
echo ""
|
||||||
|
if [ "${LICENSE_WARNINGS_EXIST}" = "true" ]; then
|
||||||
|
echo "❌ **Failed** – incompatible or unknown licenses found."
|
||||||
|
if [ -f "frontend/src/assets/license-warnings.json" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "### Warnings"
|
||||||
|
jq -r '.warnings[] | "- \(.message)"' frontend/src/assets/license-warnings.json || true
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "✅ **Passed** – no license warnings detected."
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo "_Note: This is a fork PR. PR comments are disabled; use this summary._"
|
||||||
|
} >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
|
||||||
- name: Comment on PR - License Check Results
|
- name: Comment on PR - License Check Results
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||||
with:
|
with:
|
||||||
github-token: ${{ steps.setup-bot.outputs.token }}
|
github-token: ${{ steps.setup-bot.outputs.token }}
|
||||||
|
|||||||
6628
frontend/package-lock.json
generated
6628
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -5,52 +5,49 @@
|
|||||||
"license": "SEE LICENSE IN https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/proprietary/LICENSE",
|
"license": "SEE LICENSE IN https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/proprietary/LICENSE",
|
||||||
"proxy": "http://localhost:8080",
|
"proxy": "http://localhost:8080",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@atlaskit/pragmatic-drag-and-drop": "^1.7.4",
|
"@atlaskit/pragmatic-drag-and-drop": "^1.7.7",
|
||||||
"@embedpdf/core": "^1.1.1",
|
"@embedpdf/core": "^1.2.1",
|
||||||
"@embedpdf/engines": "^1.1.1",
|
"@embedpdf/engines": "^1.2.1",
|
||||||
"@embedpdf/plugin-interaction-manager": "^1.1.1",
|
"@embedpdf/plugin-interaction-manager": "^1.2.1",
|
||||||
"@embedpdf/plugin-loader": "^1.1.1",
|
"@embedpdf/plugin-loader": "^1.2.1",
|
||||||
"@embedpdf/plugin-pan": "^1.1.1",
|
"@embedpdf/plugin-pan": "^1.2.1",
|
||||||
"@embedpdf/plugin-render": "^1.1.1",
|
"@embedpdf/plugin-render": "^1.2.1",
|
||||||
"@embedpdf/plugin-rotate": "^1.1.1",
|
"@embedpdf/plugin-rotate": "^1.2.1",
|
||||||
"@embedpdf/plugin-scroll": "^1.1.1",
|
"@embedpdf/plugin-scroll": "^1.2.1",
|
||||||
"@embedpdf/plugin-search": "^1.1.1",
|
"@embedpdf/plugin-search": "^1.2.1",
|
||||||
"@embedpdf/plugin-selection": "^1.1.1",
|
"@embedpdf/plugin-selection": "^1.2.1",
|
||||||
"@embedpdf/plugin-spread": "^1.1.1",
|
"@embedpdf/plugin-spread": "^1.2.1",
|
||||||
"@embedpdf/plugin-thumbnail": "^1.1.1",
|
"@embedpdf/plugin-thumbnail": "^1.2.1",
|
||||||
"@embedpdf/plugin-tiling": "^1.1.1",
|
"@embedpdf/plugin-tiling": "^1.2.1",
|
||||||
"@embedpdf/plugin-viewport": "^1.1.1",
|
"@embedpdf/plugin-viewport": "^1.2.1",
|
||||||
"@embedpdf/plugin-zoom": "^1.1.1",
|
"@embedpdf/plugin-zoom": "^1.2.1",
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "^11.14.0",
|
||||||
"@emotion/styled": "^11.14.0",
|
"@emotion/styled": "^11.14.1",
|
||||||
"@iconify/react": "^6.0.0",
|
"@iconify/react": "^6.0.2",
|
||||||
"@mantine/core": "^8.0.1",
|
"@mantine/core": "^8.3.1",
|
||||||
"@mantine/dates": "^8.0.1",
|
"@mantine/dates": "^8.3.1",
|
||||||
"@mantine/dropzone": "^8.0.1",
|
"@mantine/dropzone": "^8.3.1",
|
||||||
"@mantine/hooks": "^8.0.1",
|
"@mantine/hooks": "^8.3.1",
|
||||||
"@mui/icons-material": "^7.1.0",
|
"@mui/icons-material": "^7.3.2",
|
||||||
"@mui/material": "^7.1.0",
|
"@mui/material": "^7.3.2",
|
||||||
"@tailwindcss/postcss": "^4.1.8",
|
"@tailwindcss/postcss": "^4.1.13",
|
||||||
"@tanstack/react-virtual": "^3.13.12",
|
"@tanstack/react-virtual": "^3.13.12",
|
||||||
"@testing-library/dom": "^10.4.0",
|
|
||||||
"@testing-library/jest-dom": "^6.6.3",
|
|
||||||
"@testing-library/react": "^16.3.0",
|
|
||||||
"@testing-library/user-event": "^13.5.0",
|
|
||||||
"autoprefixer": "^10.4.21",
|
"autoprefixer": "^10.4.21",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.12.2",
|
||||||
"i18next": "^25.2.1",
|
"i18next": "^25.5.2",
|
||||||
"i18next-browser-languagedetector": "^8.1.0",
|
"i18next-browser-languagedetector": "^8.2.0",
|
||||||
"i18next-http-backend": "^3.0.2",
|
"i18next-http-backend": "^3.0.2",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
|
"license-report": "^6.8.0",
|
||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"pdfjs-dist": "^3.11.174",
|
"pdfjs-dist": "^5.4.149",
|
||||||
"posthog-js": "^1.261.0",
|
"posthog-js": "^1.268.0",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.1",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.1",
|
||||||
"react-i18next": "^15.5.2",
|
"react-i18next": "^15.7.3",
|
||||||
"react-router-dom": "^7.6.0",
|
"react-router-dom": "^7.9.1",
|
||||||
"tailwindcss": "^4.1.8",
|
"tailwindcss": "^4.1.13",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^5.1.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"predev": "npm run generate-icons",
|
"predev": "npm run generate-icons",
|
||||||
@ -70,12 +67,17 @@
|
|||||||
"test:coverage": "vitest --coverage",
|
"test:coverage": "vitest --coverage",
|
||||||
"test:e2e": "playwright test",
|
"test:e2e": "playwright test",
|
||||||
"test:e2e:ui": "playwright test --ui",
|
"test:e2e:ui": "playwright test --ui",
|
||||||
"test:e2e:install": "playwright install"
|
"test:e2e:install": "playwright install",
|
||||||
|
"update:minor": "npm outdated || npm update && npm audit fix && npm test",
|
||||||
|
"update:major": "npx npm-check-updates -u && npm install",
|
||||||
|
"update:interactive": "npx npm-check-updates -i",
|
||||||
|
"update:minor-strict": "npx npm-check-updates -u --target minor && npm install"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
"react-app",
|
"eslint:recommended",
|
||||||
"react-app/jest"
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"plugin:react-hooks/recommended"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
@ -91,26 +93,41 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.34.0",
|
"@eslint/js": "^9.36.0",
|
||||||
"@iconify-json/material-symbols": "^1.2.33",
|
"@iconify-json/material-symbols": "^1.2.37",
|
||||||
"@iconify/utils": "^3.0.1",
|
"@iconify/utils": "^3.0.2",
|
||||||
"@playwright/test": "^1.40.0",
|
"@playwright/test": "^1.55.0",
|
||||||
"@types/node": "^24.2.1",
|
"@testing-library/dom": "^10.4.1",
|
||||||
"@types/react": "^19.1.4",
|
"@testing-library/jest-dom": "^6.8.0",
|
||||||
"@types/react-dom": "^19.1.5",
|
"@testing-library/react": "^16.3.0",
|
||||||
"@vitejs/plugin-react": "^4.5.0",
|
"@testing-library/user-event": "^14.6.1",
|
||||||
"@vitest/coverage-v8": "^1.0.0",
|
"@types/node": "^24.5.2",
|
||||||
"eslint": "^9.34.0",
|
"@types/react": "^19.1.13",
|
||||||
"jsdom": "^23.0.0",
|
"@types/react-dom": "^19.1.9",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.44.1",
|
||||||
|
"@typescript-eslint/parser": "^8.44.1",
|
||||||
|
"@vitejs/plugin-react-swc": "^4.1.0",
|
||||||
|
"@vitest/coverage-v8": "^3.2.4",
|
||||||
|
"eslint": "^9.36.0",
|
||||||
|
"eslint-plugin-react-hooks": "^5.2.0",
|
||||||
|
"jsdom": "^27.0.0",
|
||||||
"license-checker": "^25.0.1",
|
"license-checker": "^25.0.1",
|
||||||
"madge": "^8.0.0",
|
"madge": "^8.0.0",
|
||||||
"postcss": "^8.5.3",
|
"postcss": "^8.5.6",
|
||||||
"postcss-cli": "^11.0.1",
|
"postcss-cli": "^11.0.1",
|
||||||
"postcss-preset-mantine": "^1.17.0",
|
"postcss-preset-mantine": "^1.18.0",
|
||||||
"postcss-simple-vars": "^7.0.1",
|
"postcss-simple-vars": "^7.0.1",
|
||||||
"typescript": "^5.9.2",
|
"typescript": "^5.9.2",
|
||||||
"typescript-eslint": "^8.42.0",
|
"typescript-eslint": "^8.44.1",
|
||||||
"vite": "^6.3.5",
|
"vite": "^7.1.7",
|
||||||
"vitest": "^1.0.0"
|
"vitest": "^3.2.4"
|
||||||
|
},
|
||||||
|
"depcheck": {
|
||||||
|
"ignoreMatches": [
|
||||||
|
"@emotion/*",
|
||||||
|
"tailwindcss",
|
||||||
|
"@testing-library/user-event",
|
||||||
|
"@vitest/coverage-v8"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
58353
frontend/public/pdf.worker.js
vendored
58353
frontend/public/pdf.worker.js
vendored
File diff suppressed because one or more lines are too long
@ -1,8 +1,17 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
const { execSync } = require('child_process');
|
import { execSync } from 'node:child_process';
|
||||||
const fs = require('fs');
|
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';
|
||||||
const path = require('path');
|
import * as path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
import { argv } from 'node:process';
|
||||||
|
const inputIdx = argv.indexOf('--input');
|
||||||
|
const INPUT_FILE = inputIdx > -1 ? argv[inputIdx + 1] : null;
|
||||||
|
const POSTPROCESS_ONLY = !!INPUT_FILE;
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = path.dirname(__filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate 3rd party licenses for frontend dependencies
|
* Generate 3rd party licenses for frontend dependencies
|
||||||
@ -14,28 +23,37 @@ const PACKAGE_JSON = path.join(__dirname, '..', 'package.json');
|
|||||||
|
|
||||||
// Ensure the output directory exists
|
// Ensure the output directory exists
|
||||||
const outputDir = path.dirname(OUTPUT_FILE);
|
const outputDir = path.dirname(OUTPUT_FILE);
|
||||||
if (!fs.existsSync(outputDir)) {
|
if (!existsSync(outputDir)) {
|
||||||
fs.mkdirSync(outputDir, { recursive: true });
|
mkdirSync(outputDir, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('🔍 Generating frontend license report...');
|
console.log('🔍 Generating frontend license report...');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Install license-checker if not present
|
// Safety guard: don't run this script on fork PRs (workflow setzt PR_IS_FORK)
|
||||||
try {
|
if (process.env.PR_IS_FORK === 'true' && !POSTPROCESS_ONLY) {
|
||||||
require.resolve('license-checker');
|
console.error('Fork PR detected: only --input (postprocess-only) mode is allowed.');
|
||||||
} catch {
|
process.exit(2);
|
||||||
console.log('📦 Installing license-checker...');
|
|
||||||
execSync('npm install --save-dev license-checker', { stdio: 'inherit' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate license report using license-checker (more reliable)
|
|
||||||
const licenseReport = execSync('npx license-checker --production --json', {
|
|
||||||
encoding: 'utf8',
|
|
||||||
cwd: path.dirname(PACKAGE_JSON)
|
|
||||||
});
|
|
||||||
|
|
||||||
let licenseData;
|
let licenseData;
|
||||||
|
// Generate license report using pinned license-checker; disable lifecycle scripts
|
||||||
|
if (POSTPROCESS_ONLY) {
|
||||||
|
if (!INPUT_FILE || !existsSync(INPUT_FILE)) {
|
||||||
|
console.error('❌ --input file missing or not found');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
licenseData = JSON.parse(readFileSync(INPUT_FILE, 'utf8'));
|
||||||
|
} else {
|
||||||
|
const licenseReport = execSync(
|
||||||
|
// 'npx --yes license-checker@25.0.1 --production --json',
|
||||||
|
'npx --yes license-report --only=prod --output=json',
|
||||||
|
{
|
||||||
|
encoding: 'utf8',
|
||||||
|
cwd: path.dirname(PACKAGE_JSON),
|
||||||
|
env: { ...process.env, NPM_CONFIG_IGNORE_SCRIPTS: 'true' }
|
||||||
|
}
|
||||||
|
);
|
||||||
try {
|
try {
|
||||||
licenseData = JSON.parse(licenseReport);
|
licenseData = JSON.parse(licenseReport);
|
||||||
} catch (parseError) {
|
} catch (parseError) {
|
||||||
@ -43,30 +61,16 @@ try {
|
|||||||
console.error('Raw output:', licenseReport.substring(0, 500) + '...');
|
console.error('Raw output:', licenseReport.substring(0, 500) + '...');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!licenseData || typeof licenseData !== 'object') {
|
if (!Array.isArray(licenseData)) {
|
||||||
console.error('❌ Invalid license data structure');
|
console.error('❌ Invalid license data structure');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert license-checker format to array
|
// Convert license-checker format to array
|
||||||
const licenseArray = Object.entries(licenseData).map(([key, value]) => {
|
const licenseArray = licenseData.map(dep => {
|
||||||
let name, version;
|
let licenseType = dep.licenseType;
|
||||||
|
|
||||||
// Handle scoped packages like @mantine/core@1.0.0
|
|
||||||
if (key.startsWith('@')) {
|
|
||||||
const parts = key.split('@');
|
|
||||||
name = `@${parts[1]}`;
|
|
||||||
version = parts[2];
|
|
||||||
} else {
|
|
||||||
// Handle regular packages like react@18.0.0
|
|
||||||
const lastAtIndex = key.lastIndexOf('@');
|
|
||||||
name = key.substring(0, lastAtIndex);
|
|
||||||
version = key.substring(lastAtIndex + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normalize license types for edge cases
|
|
||||||
let licenseType = value.licenses;
|
|
||||||
|
|
||||||
// Handle missing or null licenses
|
// Handle missing or null licenses
|
||||||
if (!licenseType || licenseType === null || licenseType === undefined) {
|
if (!licenseType || licenseType === null || licenseType === undefined) {
|
||||||
@ -88,13 +92,17 @@ try {
|
|||||||
licenseType = 'Unknown';
|
licenseType = 'Unknown';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( "posthog-js" === dep.name && licenseType.startsWith("SEE LICENSE IN LICENSE")) {
|
||||||
|
licenseType = "SEE LICENSE IN LICENSE https://github.com/PostHog/posthog-js/blob/main/LICENSE";
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: name,
|
name: dep.name,
|
||||||
version: version || value.version || 'unknown',
|
version: dep.installedVersion || dep.definedVersion || dep.remoteVersion || 'unknown',
|
||||||
licenseType: licenseType,
|
licenseType: licenseType,
|
||||||
repository: value.repository,
|
repository: dep.link,
|
||||||
url: value.url,
|
url: dep.link,
|
||||||
link: value.licenseUrl
|
link: dep.link
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -153,7 +161,7 @@ try {
|
|||||||
|
|
||||||
// Write license warnings to a separate file for CI/CD
|
// Write license warnings to a separate file for CI/CD
|
||||||
const warningsFile = path.join(__dirname, '..', 'src', 'assets', 'license-warnings.json');
|
const warningsFile = path.join(__dirname, '..', 'src', 'assets', 'license-warnings.json');
|
||||||
fs.writeFileSync(warningsFile, JSON.stringify({
|
writeFileSync(warningsFile, JSON.stringify({
|
||||||
warnings: problematicLicenses,
|
warnings: problematicLicenses,
|
||||||
generated: new Date().toISOString()
|
generated: new Date().toISOString()
|
||||||
}, null, 2));
|
}, null, 2));
|
||||||
@ -163,7 +171,7 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write to file
|
// Write to file
|
||||||
fs.writeFileSync(OUTPUT_FILE, JSON.stringify(transformedData, null, 4));
|
writeFileSync(OUTPUT_FILE, JSON.stringify(transformedData, null, 4));
|
||||||
|
|
||||||
console.log(`✅ License report generated successfully!`);
|
console.log(`✅ License report generated successfully!`);
|
||||||
console.log(`📄 Found ${transformedData.dependencies.length} dependencies`);
|
console.log(`📄 Found ${transformedData.dependencies.length} dependencies`);
|
||||||
@ -274,7 +282,8 @@ function checkLicenseCompatibility(licenseSummary, licenseArray) {
|
|||||||
'MIT', 'MIT*', 'Apache-2.0', 'Apache License 2.0', 'BSD-2-Clause', 'BSD-3-Clause', 'BSD',
|
'MIT', 'MIT*', 'Apache-2.0', 'Apache License 2.0', 'BSD-2-Clause', 'BSD-3-Clause', 'BSD',
|
||||||
'ISC', 'CC0-1.0', 'Public Domain', 'Unlicense', '0BSD', 'BlueOak-1.0.0',
|
'ISC', 'CC0-1.0', 'Public Domain', 'Unlicense', '0BSD', 'BlueOak-1.0.0',
|
||||||
'Zlib', 'Artistic-2.0', 'Python-2.0', 'Ruby', 'MPL-2.0', 'CC-BY-4.0',
|
'Zlib', 'Artistic-2.0', 'Python-2.0', 'Ruby', 'MPL-2.0', 'CC-BY-4.0',
|
||||||
'SEE LICENSE IN https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/proprietary/LICENSE'
|
'SEE LICENSE IN https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/proprietary/LICENSE',
|
||||||
|
'SEE LICENSE IN LICENSE https://github.com/PostHog/posthog-js/blob/main/LICENSE'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Helper function to normalize license names for comparison
|
// Helper function to normalize license names for comparison
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
1
frontend/src/global.d.ts
vendored
1
frontend/src/global.d.ts
vendored
@ -17,6 +17,7 @@ declare module '../assets/material-symbols-icons.json' {
|
|||||||
export default value;
|
export default value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module 'pdfjs-dist/legacy/build/pdf.mjs'
|
||||||
// TODO: Add proper EmbedPDF types for local submodule integration
|
// TODO: Add proper EmbedPDF types for local submodule integration
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export function usePDFProcessor() {
|
|||||||
throw new Error('Could not get canvas context');
|
throw new Error('Could not get canvas context');
|
||||||
}
|
}
|
||||||
|
|
||||||
await page.render({ canvasContext: context, viewport }).promise;
|
await page.render({ canvasContext: context, viewport, canvas }).promise;
|
||||||
const thumbnail = canvas.toDataURL();
|
const thumbnail = canvas.toDataURL();
|
||||||
|
|
||||||
// Clean up using worker manager
|
// Clean up using worker manager
|
||||||
|
|||||||
@ -110,7 +110,7 @@ export class PDFProcessingService {
|
|||||||
|
|
||||||
const context = canvas.getContext('2d');
|
const context = canvas.getContext('2d');
|
||||||
if (context) {
|
if (context) {
|
||||||
await page.render({ canvasContext: context, viewport }).promise;
|
await page.render({ canvasContext: context, viewport, canvas }).promise;
|
||||||
const thumbnail = canvas.toDataURL();
|
const thumbnail = canvas.toDataURL();
|
||||||
|
|
||||||
pages.push({
|
pages.push({
|
||||||
|
|||||||
@ -5,9 +5,7 @@
|
|||||||
* and ensuring proper cleanup when operations complete.
|
* and ensuring proper cleanup when operations complete.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as pdfjsLib from 'pdfjs-dist';
|
import { GlobalWorkerOptions, getDocument, PDFDocumentProxy } from 'pdfjs-dist/legacy/build/pdf.mjs';
|
||||||
import { PDFDocumentProxy } from 'pdfjs-dist/types/src/display/api';
|
|
||||||
const { getDocument, GlobalWorkerOptions } = pdfjsLib;
|
|
||||||
|
|
||||||
class PDFWorkerManager {
|
class PDFWorkerManager {
|
||||||
private static instance: PDFWorkerManager;
|
private static instance: PDFWorkerManager;
|
||||||
@ -32,7 +30,10 @@ class PDFWorkerManager {
|
|||||||
*/
|
*/
|
||||||
private initializeWorker(): void {
|
private initializeWorker(): void {
|
||||||
if (!this.isInitialized) {
|
if (!this.isInitialized) {
|
||||||
GlobalWorkerOptions.workerSrc = '/pdf.worker.js';
|
GlobalWorkerOptions.workerSrc = new URL(
|
||||||
|
'pdfjs-dist/legacy/build/pdf.worker.min.mjs',
|
||||||
|
import.meta.url
|
||||||
|
).toString();
|
||||||
this.isInitialized = true;
|
this.isInitialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -410,7 +410,7 @@ export async function generateThumbnailWithMetadata(file: File): Promise<Thumbna
|
|||||||
throw new Error('Could not get canvas context');
|
throw new Error('Could not get canvas context');
|
||||||
}
|
}
|
||||||
|
|
||||||
await page.render({ canvasContext: context, viewport }).promise;
|
await page.render({ canvasContext: context, viewport, canvas }).promise;
|
||||||
const thumbnail = canvas.toDataURL();
|
const thumbnail = canvas.toDataURL();
|
||||||
|
|
||||||
pdfWorkerManager.destroyDocument(pdf);
|
pdfWorkerManager.destroyDocument(pdf);
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react-swc';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { defineConfig } from 'vitest/config'
|
import { defineConfig } from 'vitest/config'
|
||||||
import react from '@vitejs/plugin-react'
|
import react from '@vitejs/plugin-react-swc';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user