From 0e4db121a0e611209b253cb8ac0c0c6f40697c21 Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Sat, 21 Feb 2026 00:28:45 -0300
Subject: [PATCH 01/10] ci: update workflows
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
.github/workflows/node.yml | 2 +-
.github/workflows/npm-publish.yml | 2 +-
.github/workflows/pages.yml | 21 ++++++++++---
.github/workflows/tests.yml | 52 +++++++++++++++++++++++++++++++
4 files changed, 70 insertions(+), 7 deletions(-)
create mode 100644 .github/workflows/tests.yml
diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml
index a83e4e3..bf4f3bd 100644
--- a/.github/workflows/node.yml
+++ b/.github/workflows/node.yml
@@ -52,7 +52,7 @@ jobs:
run: npm run lint
- name: Build library
- run: npm run build:lib
+ run: npm run build
- name: Check build changes
run: |
diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml
index e4a293a..0a2a906 100644
--- a/.github/workflows/npm-publish.yml
+++ b/.github/workflows/npm-publish.yml
@@ -47,7 +47,7 @@ jobs:
CYPRESS_INSTALL_BINARY: 0
run: |
npm i
- npm run build:lib
+ npm run build
- name: Publish to npm
run: npm publish --provenance --access public
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index 5c014b2..bc697bc 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
# SPDX-License-Identifier: AGPL-3.0-or-later
-name: Deploy A DEMO
+name: Deploy Demo
on:
workflow_dispatch:
@@ -16,17 +16,28 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- - name: Set up Node.js
+ - name: Read package.json node and npm engines version
+ uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
+ id: versions
+ with:
+ fallbackNode: '^20'
+ fallbackNpm: '^10'
+
+ - name: Set up node ${{ steps.versions.outputs.nodeVersion }}
uses: actions/setup-node@v4
+ with:
+ node-version: ${{ steps.versions.outputs.nodeVersion }}
+
+ - name: Set up npm ${{ steps.versions.outputs.npmVersion }}
+ run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
- name: Install & Build
run: |
npm i
- npm install -g cross-env
- cross-env PUBLIC_PATH=/pdf-elements/ npm run build
+ npm run build:demo
- name: Deploy
uses: JamesIves/github-pages-deploy-action@v4
with:
branch: gh-pages
- folder: dist
+ folder: dist-demo
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 0000000..a572b9f
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,52 @@
+# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+name: Tests
+
+on:
+ pull_request:
+ push:
+ branches:
+ - main
+
+permissions:
+ contents: read
+
+concurrency:
+ group: tests-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ name: NPM test
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ persist-credentials: false
+
+ - name: Read package.json node and npm engines version
+ uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
+ id: versions
+ with:
+ fallbackNode: '^20'
+ fallbackNpm: '^10'
+
+ - name: Set up node ${{ steps.versions.outputs.nodeVersion }}
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ steps.versions.outputs.nodeVersion }}
+
+ - name: Set up npm ${{ steps.versions.outputs.npmVersion }}
+ run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
+
+ - name: Install dependencies
+ env:
+ CYPRESS_INSTALL_BINARY: 0
+ PUPPETEER_SKIP_DOWNLOAD: true
+ run: npm i
+
+ - name: Test
+ run: npm run test
From 5c0449450eaa0e9e1defd152357a10cc991767c0 Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Sat, 21 Feb 2026 00:30:50 -0300
Subject: [PATCH 02/10] chore: update tooling config
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
.eslintrc.js | 16 ++++++++++--
.npmignore | 6 ++++-
REUSE.toml | 6 ++++-
env.d.ts | 7 ++++++
package.json | 58 +++++++++++++++++++++++++++---------------
tsconfig.json | 18 ++++++++++++++
vite.config.ts | 65 ++++++++++++++++++++++++++++++++++++++++++++++++
vitest.config.ts | 13 ++++++++++
vue.config.js | 29 ---------------------
9 files changed, 165 insertions(+), 53 deletions(-)
create mode 100644 env.d.ts
create mode 100644 tsconfig.json
create mode 100644 vite.config.ts
create mode 100644 vitest.config.ts
delete mode 100644 vue.config.js
diff --git a/.eslintrc.js b/.eslintrc.js
index db56d42..47fa709 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -11,11 +11,23 @@ module.exports = {
extends: [
'plugin:vue/essential',
'eslint:recommended',
+ 'plugin:@typescript-eslint/recommended',
],
parserOptions: {
- parser: '@babel/eslint-parser',
- requireConfigFile: false,
+ parser: '@typescript-eslint/parser',
+ ecmaVersion: 2021,
+ sourceType: 'module',
},
+ parser: 'vue-eslint-parser',
+ overrides: [
+ {
+ files: ['tests/**/*.ts'],
+ env: {
+ 'vitest/globals': true,
+ },
+ plugins: ['vitest'],
+ },
+ ],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
diff --git a/.npmignore b/.npmignore
index 438781d..534324e 100644
--- a/.npmignore
+++ b/.npmignore
@@ -4,12 +4,16 @@
# Source files
src/
examples/
+tests/
# Config files
.babelrc
.eslintrc.js
-vue.config.js
+env.d.ts
postcss.config.js
+tsconfig.json
+vite.config.ts
+vitest.config.ts
REUSE.toml
LICENSES/
CONTRIBUTING.md
diff --git a/REUSE.toml b/REUSE.toml
index a6d2e50..90cb2c5 100644
--- a/REUSE.toml
+++ b/REUSE.toml
@@ -12,11 +12,15 @@ default-copyright = "2025 LibreCode coop and contributors"
path = [
".babelrc",
".eslintrc.js",
+ "env.d.ts",
"package.json",
"package-lock.json",
"postcss.config.js",
- "vue.config.js",
+ "tsconfig.json",
+ "vite.config.ts",
+ "vitest.config.ts",
"examples/**",
+ "tests/**",
"dist/**",
]
precedence = "aggregate"
diff --git a/env.d.ts b/env.d.ts
new file mode 100644
index 0000000..323c78a
--- /dev/null
+++ b/env.d.ts
@@ -0,0 +1,7 @@
+///
+
+declare module '*.vue' {
+ import type { DefineComponent } from 'vue'
+ const component: DefineComponent<{}, {}, any>
+ export default component
+}
diff --git a/package.json b/package.json
index d8a5a9a..29ab32b 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,18 @@
{
"name": "@libresign/pdf-elements",
- "description": "PDF viewer with draggable and resizable element overlays for Vue 2",
+ "description": "PDF viewer with draggable and resizable element overlays for Vue 3",
"version": "0.4.0",
"author": "LibreCode ",
"private": false,
- "main": "dist/pdf-elements.umd.js",
- "module": "dist/pdf-elements.esm.js",
+ "main": "dist/index.js",
+ "module": "dist/index.js",
+ "types": "dist/index.d.ts",
+ "exports": {
+ ".": {
+ "import": "./dist/index.js",
+ "types": "./dist/index.d.ts"
+ }
+ },
"repository": {
"type": "git",
"url": "https://github.com/LibreSign/pdf-elements"
@@ -21,31 +28,41 @@
"draggable",
"resizable",
"libresign",
- "vue2"
+ "vue3"
],
"scripts": {
- "serve": "vue-cli-service serve",
- "build": "vue-cli-service build",
- "build:lib": "vue-cli-service build --target lib --name pdf-elements src/index.js",
- "lint": "vue-cli-service lint --no-fix",
- "lint:fix": "vue-cli-service lint"
+ "dev": "vite",
+ "build": "vite build",
+ "build:report": "vite build --mode report",
+ "build:demo": "vite build --mode demo",
+ "preview:demo": "vite preview --outDir dist-demo",
+ "test": "vitest run",
+ "test:watch": "vitest",
+ "lint": "eslint . --ext .vue,.ts,.js --max-warnings=0",
+ "lint:fix": "eslint . --ext .vue,.ts,.js --fix"
},
"dependencies": {
- "pdfjs-dist": "^5.4.530",
- "vue": "^2.7.16"
+ "pdfjs-dist": "^5.4.624",
+ "vue": "^3.5.28"
},
"devDependencies": {
- "@babel/core": "^7.28.6",
- "@babel/eslint-parser": "^7.28.6",
- "@babel/plugin-transform-private-methods": "^7.28.6",
"@nextcloud/browserslist-config": "^3.1.2",
- "@vue/cli-plugin-babel": "^5.0.9",
- "@vue/cli-plugin-eslint": "^5.0.9",
- "@vue/cli-service": "^5.0.9",
- "eslint": "^8.57.1",
- "eslint-plugin-vue": "^9.24.0",
+ "@typescript-eslint/eslint-plugin": "^8.56.0",
+ "@typescript-eslint/parser": "^8.56.0",
+ "@vitejs/plugin-vue": "^6.0.4",
+ "eslint": "^9.0.0",
+ "eslint-plugin-vue": "^10.8.0",
+ "eslint-plugin-vitest": "^0.5.4",
+ "happy-dom": "^20.7.0",
"postcss": "^8.5.6",
- "vue-template-compiler": "^2.7.16"
+ "rollup-plugin-visualizer": "^7.0.0",
+ "typescript": "^5.9.3",
+ "vite": "^7.3.1",
+ "vite-plugin-dts": "^4.5.4",
+ "vitest": "^4.0.18",
+ "@vue/test-utils": "^2.4.6",
+ "vue-eslint-parser": "^10.4.0",
+ "vue-tsc": "^3.2.4"
},
"browserslist": [
"extends @nextcloud/browserslist-config"
@@ -56,5 +73,6 @@
"COPYING",
"README.md"
],
+ "sideEffects": false,
"license": "AGPL-3.0-or-later"
}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..7f3dc82
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "module": "NodeNext",
+ "moduleResolution": "NodeNext",
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "jsx": "preserve",
+ "strict": false,
+ "noImplicitAny": false,
+ "skipLibCheck": true,
+ "useDefineForClassFields": true,
+ "resolveJsonModule": true,
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "types": ["vite/client", "vitest/globals"]
+ },
+ "include": ["env.d.ts", "src", "examples", "tests"]
+}
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 0000000..81dfc3d
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,65 @@
+// SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+import path from 'node:path'
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import dts from 'vite-plugin-dts'
+
+export default defineConfig(async ({ command, mode }) => {
+ const isDemo = command === 'serve' || mode === 'demo'
+ const plugins = [vue()]
+
+ if (!isDemo) {
+ plugins.push(
+ dts({
+ entryRoot: 'src',
+ outDir: 'dist',
+ insertTypesEntry: true,
+ include: ['src'],
+ exclude: ['examples', 'tests'],
+ })
+ )
+ }
+
+ if (mode === 'report') {
+ const { visualizer } = await import('rollup-plugin-visualizer')
+ plugins.push(
+ visualizer({
+ filename: 'dist/bundle-report.html',
+ gzipSize: true,
+ brotliSize: true,
+ open: false,
+ })
+ )
+ }
+
+ return {
+ root: isDemo ? 'examples' : undefined,
+ server: {
+ host: '0.0.0.0',
+ },
+ plugins,
+ build: isDemo
+ ? {
+ outDir: path.resolve(__dirname, 'dist-demo'),
+ emptyOutDir: true,
+ }
+ : {
+ lib: {
+ entry: path.resolve(__dirname, 'src/index.ts'),
+ name: 'PDFElements',
+ formats: ['es'],
+ fileName: 'index',
+ },
+ rollupOptions: {
+ external: ['vue'],
+ output: {
+ globals: {
+ vue: 'Vue',
+ },
+ },
+ },
+ },
+ }
+})
diff --git a/vitest.config.ts b/vitest.config.ts
new file mode 100644
index 0000000..e361d00
--- /dev/null
+++ b/vitest.config.ts
@@ -0,0 +1,13 @@
+// SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+import { defineConfig } from 'vitest/config'
+import vue from '@vitejs/plugin-vue'
+
+export default defineConfig({
+ plugins: [vue()],
+ test: {
+ environment: 'happy-dom',
+ include: ['tests/**/*.spec.ts'],
+ },
+})
diff --git a/vue.config.js b/vue.config.js
deleted file mode 100644
index 528658b..0000000
--- a/vue.config.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
-// SPDX-License-Identifier: AGPL-3.0-or-later
-
-module.exports = {
- publicPath: process.env.PUBLIC_PATH || '/',
- pages: {
- index: {
- entry: 'examples/main.js',
- template: 'examples/index.html',
- filename: 'index.html',
- },
- },
- configureWebpack: {
- output: {
- libraryExport: 'default',
- },
- module: {
- rules: [
- {
- test: /pdf\.worker(\.min)?\.mjs$/,
- type: 'asset/resource',
- generator: {
- filename: '[name][ext]',
- },
- },
- ],
- },
- },
-}
From 640c719e3d6ef2edb2e8b3d8e7e66c119c1093f9 Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Sat, 21 Feb 2026 00:31:02 -0300
Subject: [PATCH 03/10] feat: migrate core components and utils
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
src/components/DraggableElement.vue | 33 ++--
src/components/PDFElements.vue | 145 +++++++++++-------
src/components/PDFPage.vue | 14 +-
src/index.js | 17 --
src/index.ts | 18 +++
src/types.ts | 35 +++++
src/utils/asyncReader.js | 44 ------
src/utils/asyncReader.ts | 103 +++++++++++++
src/utils/{geometry.js => geometry.ts} | 18 ++-
.../{measurements.js => measurements.ts} | 21 ++-
src/utils/{objectStore.js => objectStore.ts} | 19 ++-
src/utils/{pageBounds.js => pageBounds.ts} | 4 +-
src/utils/{zoom.js => zoom.ts} | 4 +-
13 files changed, 325 insertions(+), 150 deletions(-)
delete mode 100644 src/index.js
create mode 100644 src/index.ts
create mode 100644 src/types.ts
delete mode 100644 src/utils/asyncReader.js
create mode 100644 src/utils/asyncReader.ts
rename src/utils/{geometry.js => geometry.ts} (67%)
rename src/utils/{measurements.js => measurements.ts} (50%)
rename src/utils/{objectStore.js => objectStore.ts} (65%)
rename src/utils/{pageBounds.js => pageBounds.ts} (59%)
rename src/utils/{zoom.js => zoom.ts} (60%)
diff --git a/src/components/DraggableElement.vue b/src/components/DraggableElement.vue
index 9fb646e..4e9188d 100644
--- a/src/components/DraggableElement.vue
+++ b/src/components/DraggableElement.vue
@@ -54,12 +54,15 @@ SPDX-License-Identifier: AGPL-3.0-or-later
-