diff --git a/README.md b/README.md
index 1a19c9e..bed6509 100644
--- a/README.md
+++ b/README.md
@@ -58,6 +58,17 @@ A plugin that does one thing only: **Detect** and **Manage** duplicate items in
# Changelog
+## v3.0.6
+
+
+ Click here to show more.
+
+In this version, we have updated the dependencies and adapted to the latest version of Zotero.
+
+Thanks to [pascaloettli](https://github.com/pascaloettli) for the feedback in [issue #131](https://github.com/ChenglongMa/zoplicate/issues/131).
+
+
+
## v3.0.5
diff --git a/addon/manifest.json b/addon/manifest.json
index 6600a67..ad827f4 100644
--- a/addon/manifest.json
+++ b/addon/manifest.json
@@ -14,7 +14,7 @@
"id": "__addonID__",
"update_url": "__updateURL__",
"strict_min_version": "6.999",
- "strict_max_version": "7.0.*"
+ "strict_max_version": "7.*"
}
}
}
diff --git a/package-lock.json b/package-lock.json
index 5891698..a7d9018 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,22 +1,22 @@
{
"name": "zoplicate",
- "version": "3.1.0",
+ "version": "3.0.6",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "zoplicate",
- "version": "3.1.0",
+ "version": "3.0.6",
"license": "AGPL-3.0-or-later",
"dependencies": {
- "zotero-plugin-toolkit": "^4.0.11"
+ "zotero-plugin-toolkit": "^4.1.1"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
- "@types/node": "^22.10.1",
- "@typescript-eslint/eslint-plugin": "^8.17.0",
- "@typescript-eslint/parser": "^8.17.0",
- "eslint": "^9.16.0",
+ "@types/node": "^22.10.5",
+ "@typescript-eslint/eslint-plugin": "^8.19.1",
+ "@typescript-eslint/parser": "^8.19.1",
+ "eslint": "^9.17.0",
"eslint-config-prettier": "^9.1.0",
"fake-indexeddb": "^6.0.0",
"jest": "^29.7.0",
@@ -25,7 +25,7 @@
"ts-node": "^10.9.2",
"typescript": "^5.7.2",
"zotero-plugin-scaffold": "^0.1.7",
- "zotero-types": "3.0.3"
+ "zotero-types": "3.1.2"
}
},
"node_modules/@ampproject/remapping": {
@@ -1274,9 +1274,9 @@
}
},
"node_modules/@eslint/js": {
- "version": "9.16.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.16.0.tgz",
- "integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==",
+ "version": "9.17.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz",
+ "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2286,6 +2286,7 @@
"integrity": "sha512-YcFhXQcp+b2d38zFOJNbpyPHnIL7KAEkhJQ+UeeKI5IpE9B8Cpf/M6RiHPQXSsSqnYbrfFylnW49dyh2oeSblQ==",
"license": "MIT",
"optional": true,
+ "peer": true,
"engines": {
"node": ">= 10"
},
@@ -2314,6 +2315,7 @@
"os": [
"android"
],
+ "peer": true,
"engines": {
"node": ">= 10"
}
@@ -2330,6 +2332,7 @@
"os": [
"darwin"
],
+ "peer": true,
"engines": {
"node": ">= 10"
}
@@ -2346,6 +2349,7 @@
"os": [
"darwin"
],
+ "peer": true,
"engines": {
"node": ">= 10"
}
@@ -2362,6 +2366,7 @@
"os": [
"linux"
],
+ "peer": true,
"engines": {
"node": ">= 10"
}
@@ -2378,6 +2383,7 @@
"os": [
"linux"
],
+ "peer": true,
"engines": {
"node": ">= 10"
}
@@ -2394,6 +2400,7 @@
"os": [
"linux"
],
+ "peer": true,
"engines": {
"node": ">= 10"
}
@@ -2410,6 +2417,7 @@
"os": [
"linux"
],
+ "peer": true,
"engines": {
"node": ">= 10"
}
@@ -2426,6 +2434,7 @@
"os": [
"linux"
],
+ "peer": true,
"engines": {
"node": ">= 10"
}
@@ -2442,6 +2451,7 @@
"os": [
"linux"
],
+ "peer": true,
"engines": {
"node": ">= 10"
}
@@ -2458,6 +2468,7 @@
"os": [
"win32"
],
+ "peer": true,
"engines": {
"node": ">= 10"
}
@@ -3018,7 +3029,8 @@
"version": "3.5.42",
"resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.42.tgz",
"integrity": "sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/@types/estree": {
"version": "1.0.6",
@@ -3073,6 +3085,7 @@
"integrity": "sha512-tJxahnjm9dEI1X+hQSC5f2BSd/coZaqbIl1m3TCl0q9SVuC52XcXfV0XmoCU1+PmjyucuVITwoTnN8OlTbEXXA==",
"deprecated": "This is a stub types definition for localforage (https://github.com/localForage/localForage). localforage provides its own type definitions, so you don't need @types/localforage installed!",
"license": "MIT",
+ "peer": true,
"dependencies": {
"localforage": "*"
}
@@ -3085,9 +3098,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "22.10.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz",
- "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==",
+ "version": "22.10.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz",
+ "integrity": "sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3106,13 +3119,15 @@
"version": "15.7.13",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
"integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/@types/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz",
"integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
@@ -3158,21 +3173,21 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.17.0.tgz",
- "integrity": "sha512-HU1KAdW3Tt8zQkdvNoIijfWDMvdSweFYm4hWh+KwhPstv+sCmWb89hCIP8msFm9N1R/ooh9honpSuvqKWlYy3w==",
+ "version": "8.19.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.19.1.tgz",
+ "integrity": "sha512-tJzcVyvvb9h/PB96g30MpxACd9IrunT7GF9wfA9/0TJ1LxGOJx1TdPzSbBBnNED7K9Ka8ybJsnEpiXPktolTLg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.17.0",
- "@typescript-eslint/type-utils": "8.17.0",
- "@typescript-eslint/utils": "8.17.0",
- "@typescript-eslint/visitor-keys": "8.17.0",
+ "@typescript-eslint/scope-manager": "8.19.1",
+ "@typescript-eslint/type-utils": "8.19.1",
+ "@typescript-eslint/utils": "8.19.1",
+ "@typescript-eslint/visitor-keys": "8.19.1",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
- "ts-api-utils": "^1.3.0"
+ "ts-api-utils": "^2.0.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3183,25 +3198,21 @@
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
- "eslint": "^8.57.0 || ^9.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.17.0.tgz",
- "integrity": "sha512-Drp39TXuUlD49F7ilHHCG7TTg8IkA+hxCuULdmzWYICxGXvDXmDmWEjJYZQYgf6l/TFfYNE167m7isnc3xlIEg==",
+ "version": "8.19.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.19.1.tgz",
+ "integrity": "sha512-67gbfv8rAwawjYx3fYArwldTQKoYfezNUT4D5ioWetr/xCrxXxvleo3uuiFuKfejipvq+og7mjz3b0G2bVyUCw==",
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "MIT",
"dependencies": {
- "@typescript-eslint/scope-manager": "8.17.0",
- "@typescript-eslint/types": "8.17.0",
- "@typescript-eslint/typescript-estree": "8.17.0",
- "@typescript-eslint/visitor-keys": "8.17.0",
+ "@typescript-eslint/scope-manager": "8.19.1",
+ "@typescript-eslint/types": "8.19.1",
+ "@typescript-eslint/typescript-estree": "8.19.1",
+ "@typescript-eslint/visitor-keys": "8.19.1",
"debug": "^4.3.4"
},
"engines": {
@@ -3212,23 +3223,19 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.17.0.tgz",
- "integrity": "sha512-/ewp4XjvnxaREtqsZjF4Mfn078RD/9GmiEAtTeLQ7yFdKnqwTOgRMSvFz4et9U5RiJQ15WTGXPLj89zGusvxBg==",
+ "version": "8.19.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.19.1.tgz",
+ "integrity": "sha512-60L9KIuN/xgmsINzonOcMDSB8p82h95hoBfSBtXuO4jlR1R9L1xSkmVZKgCPVfavDlXihh4ARNjXhh1gGnLC7Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.17.0",
- "@typescript-eslint/visitor-keys": "8.17.0"
+ "@typescript-eslint/types": "8.19.1",
+ "@typescript-eslint/visitor-keys": "8.19.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3239,16 +3246,16 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.17.0.tgz",
- "integrity": "sha512-q38llWJYPd63rRnJ6wY/ZQqIzPrBCkPdpIsaCfkR3Q4t3p6sb422zougfad4TFW9+ElIFLVDzWGiGAfbb/v2qw==",
+ "version": "8.19.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.19.1.tgz",
+ "integrity": "sha512-Rp7k9lhDKBMRJB/nM9Ksp1zs4796wVNyihG9/TU9R6KCJDNkQbc2EOKjrBtLYh3396ZdpXLtr/MkaSEmNMtykw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/typescript-estree": "8.17.0",
- "@typescript-eslint/utils": "8.17.0",
+ "@typescript-eslint/typescript-estree": "8.19.1",
+ "@typescript-eslint/utils": "8.19.1",
"debug": "^4.3.4",
- "ts-api-utils": "^1.3.0"
+ "ts-api-utils": "^2.0.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3258,18 +3265,14 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
}
},
"node_modules/@typescript-eslint/types": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.17.0.tgz",
- "integrity": "sha512-gY2TVzeve3z6crqh2Ic7Cr+CAv6pfb0Egee7J5UAVWCpVvDI/F71wNfolIim4FE6hT15EbpZFVUj9j5i38jYXA==",
+ "version": "8.19.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.19.1.tgz",
+ "integrity": "sha512-JBVHMLj7B1K1v1051ZaMMgLW4Q/jre5qGK0Ew6UgXz1Rqh+/xPzV1aW581OM00X6iOfyr1be+QyW8LOUf19BbA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3281,20 +3284,20 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.17.0.tgz",
- "integrity": "sha512-JqkOopc1nRKZpX+opvKqnM3XUlM7LpFMD0lYxTqOTKQfCWAmxw45e3qlOCsEqEB2yuacujivudOFpCnqkBDNMw==",
+ "version": "8.19.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.19.1.tgz",
+ "integrity": "sha512-jk/TZwSMJlxlNnqhy0Eod1PNEvCkpY6MXOXE/WLlblZ6ibb32i2We4uByoKPv1d0OD2xebDv4hbs3fm11SMw8Q==",
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.17.0",
- "@typescript-eslint/visitor-keys": "8.17.0",
+ "@typescript-eslint/types": "8.19.1",
+ "@typescript-eslint/visitor-keys": "8.19.1",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
- "ts-api-utils": "^1.3.0"
+ "ts-api-utils": "^2.0.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3303,23 +3306,21 @@
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.8.0"
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.17.0.tgz",
- "integrity": "sha512-bQC8BnEkxqG8HBGKwG9wXlZqg37RKSMY7v/X8VEWD8JG2JuTHuNK0VFvMPMUKQcbk6B+tf05k+4AShAEtCtJ/w==",
+ "version": "8.19.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.19.1.tgz",
+ "integrity": "sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "8.17.0",
- "@typescript-eslint/types": "8.17.0",
- "@typescript-eslint/typescript-estree": "8.17.0"
+ "@typescript-eslint/scope-manager": "8.19.1",
+ "@typescript-eslint/types": "8.19.1",
+ "@typescript-eslint/typescript-estree": "8.19.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3329,22 +3330,18 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.17.0.tgz",
- "integrity": "sha512-1Hm7THLpO6ww5QU6H/Qp+AusUUl+z/CAm3cNZZ0jQvon9yicgO7Rwd+/WWRpMKLYV6p2UvdbR27c86rzCPpreg==",
+ "version": "8.19.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.19.1.tgz",
+ "integrity": "sha512-fzmjU8CHK853V/avYZAvuVut3ZTfwN5YtMaoi+X9Y9MA9keaWNHC3zEQ9zvyX/7Hj+5JkNyK1l7TOR2hevHB6Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.17.0",
+ "@typescript-eslint/types": "8.19.1",
"eslint-visitor-keys": "^4.2.0"
},
"engines": {
@@ -3381,6 +3378,7 @@
"integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==",
"deprecated": "this version is no longer supported, please update to at least 0.8.*",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=10.0.0"
}
@@ -5458,6 +5456,7 @@
"integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==",
"hasInstallScript": true,
"license": "MIT",
+ "peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
@@ -5545,13 +5544,15 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/d": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
"integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
"license": "ISC",
+ "peer": true,
"dependencies": {
"es5-ext": "^0.10.64",
"type": "^2.7.2"
@@ -6031,6 +6032,7 @@
"resolved": "https://registry.npmjs.org/epubjs/-/epubjs-0.3.93.tgz",
"integrity": "sha512-c06pNSdBxcXv3dZSbXAVLE1/pmleRhOT6mXNZo6INKmvuKpYB65MwU/lO7830czCtjIiK9i+KR+3S+p0wtljrw==",
"license": "BSD-2-Clause",
+ "peer": true,
"dependencies": {
"@types/localforage": "0.0.34",
"@xmldom/xmldom": "^0.7.5",
@@ -6069,6 +6071,7 @@
"integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
"hasInstallScript": true,
"license": "ISC",
+ "peer": true,
"dependencies": {
"es6-iterator": "^2.0.3",
"es6-symbol": "^3.1.3",
@@ -6091,6 +6094,7 @@
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
"integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"d": "1",
"es5-ext": "^0.10.35",
@@ -6102,6 +6106,7 @@
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
"integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
"license": "ISC",
+ "peer": true,
"dependencies": {
"d": "^1.0.2",
"ext": "^1.7.0"
@@ -6186,9 +6191,9 @@
}
},
"node_modules/eslint": {
- "version": "9.16.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.16.0.tgz",
- "integrity": "sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==",
+ "version": "9.17.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz",
+ "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6197,7 +6202,7 @@
"@eslint/config-array": "^0.19.0",
"@eslint/core": "^0.9.0",
"@eslint/eslintrc": "^3.2.0",
- "@eslint/js": "9.16.0",
+ "@eslint/js": "9.17.0",
"@eslint/plugin-kit": "^0.2.3",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
@@ -6206,7 +6211,7 @@
"@types/json-schema": "^7.0.15",
"ajv": "^6.12.4",
"chalk": "^4.0.0",
- "cross-spawn": "^7.0.5",
+ "cross-spawn": "^7.0.6",
"debug": "^4.3.2",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^8.2.0",
@@ -6326,6 +6331,7 @@
"resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz",
"integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
"license": "ISC",
+ "peer": true,
"dependencies": {
"d": "^1.0.1",
"es5-ext": "^0.10.62",
@@ -6429,6 +6435,7 @@
"resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
"integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"d": "1",
"es5-ext": "~0.10.14"
@@ -6507,6 +6514,7 @@
"resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
"integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
"license": "ISC",
+ "peer": true,
"dependencies": {
"type": "^2.7.2"
}
@@ -8704,6 +8712,7 @@
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
"integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
"license": "Apache-2.0",
+ "peer": true,
"dependencies": {
"lie": "3.1.1"
}
@@ -8713,6 +8722,7 @@
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
"integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"immediate": "~3.0.5"
}
@@ -8736,7 +8746,8 @@
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/lodash.memoize": {
"version": "4.1.2",
@@ -8806,7 +8817,8 @@
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/marks-pane/-/marks-pane-1.0.9.tgz",
"integrity": "sha512-Ahs4oeG90tbdPWwAJkAAoHg2lRR8lAs9mZXETNPO9hYg3AkjUJBKi1NQ4aaIQZVGrig7c/3NUV1jANl8rFTeMg==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/marky": {
"version": "1.2.5",
@@ -9070,7 +9082,8 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
"integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
- "license": "ISC"
+ "license": "ISC",
+ "peer": true
},
"node_modules/node-fetch-native": {
"version": "1.6.4",
@@ -9739,7 +9752,8 @@
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/path-webpack/-/path-webpack-0.0.3.tgz",
"integrity": "sha512-AmeDxedoo5svf7aB3FYqSAKqMxys014lVKBzy1o/5vv9CtU7U4wgGWL1dA2o6MOzcD53ScN4Jmiq6VbtLz1vIQ==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/pathe": {
"version": "1.1.2",
@@ -9753,6 +9767,7 @@
"resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.9.124.tgz",
"integrity": "sha512-yAoM7C+IYIG23dAZHE2KqtE5exEj067Ef6oblb+AHiqLwTJSQOMB+e8ftBA3pp1+6TyE4xeofoHcu9t7XaOE0g==",
"license": "Apache-2.0",
+ "peer": true,
"engines": {
"node": ">=20"
},
@@ -11253,16 +11268,16 @@
}
},
"node_modules/ts-api-utils": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
- "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz",
+ "integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=16"
+ "node": ">=18.12"
},
"peerDependencies": {
- "typescript": ">=4.2.0"
+ "typescript": ">=4.8.4"
}
},
"node_modules/ts-jest": {
@@ -11361,7 +11376,8 @@
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz",
"integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==",
- "license": "ISC"
+ "license": "ISC",
+ "peer": true
},
"node_modules/type-check": {
"version": "0.4.0",
@@ -12204,40 +12220,27 @@
}
},
"node_modules/zotero-plugin-toolkit": {
- "version": "4.0.11",
- "resolved": "https://registry.npmjs.org/zotero-plugin-toolkit/-/zotero-plugin-toolkit-4.0.11.tgz",
- "integrity": "sha512-vDuJ+ARLrELZHL0sZqsAwHA+igrDbJ4DnJ/Bx/cbpJmf+3MB2j+dvBBvz3R+xj5EMTUoQb5XC46HHNm7JWMAuQ==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/zotero-plugin-toolkit/-/zotero-plugin-toolkit-4.1.1.tgz",
+ "integrity": "sha512-oVepinex25MJHF3jksWw7VxQF8m9tMWkc7abgJFwDtT/brYrUGlLuJFRovQKLFIxpXQJOPs8SIok7rQgDv5XCA==",
"license": "MIT",
- "dependencies": {
- "zotero-types": "^2.2.0"
- },
"engines": {
"node": ">=18"
- }
- },
- "node_modules/zotero-plugin-toolkit/node_modules/zotero-types": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/zotero-types/-/zotero-types-2.2.1.tgz",
- "integrity": "sha512-alsjWn7i3pJq7b9+2XT2WbxZtWk4WWH4EIUi6o+Xx7/uz8TQDA0PFY2mS91gL8VXWKXMrSBJKYEbkvMMR6KuKA==",
- "license": "MIT",
- "dependencies": {
- "@types/bluebird": "^3.5.42",
- "@types/react": "18.3.1",
- "epubjs": "^0.3.93",
- "pdfjs-dist": "^4.4.0"
+ },
+ "peerDependencies": {
+ "zotero-types": "^3.1.0"
}
},
"node_modules/zotero-types": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/zotero-types/-/zotero-types-3.0.3.tgz",
- "integrity": "sha512-dOGVXzrQWNw/FetuFQcn3A9U6DaaRRLvJtBRA0TLM9ArW05veJGz12cXgiGZNn0BRhq9sixOwBh+mgFygyIq1Q==",
- "dev": true,
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/zotero-types/-/zotero-types-3.1.2.tgz",
+ "integrity": "sha512-+dk4EVe7d5xKxCdFAV4TjEbflII7asTFV06F/MwaKNV/A9Hrf8o4HLbK33NqNsjz2/Mi+nrTOlKx1gvLcTKd2w==",
"license": "MIT",
- "dependencies": {
- "@types/bluebird": "^3.5.42",
- "@types/react": "18.3.1",
- "epubjs": "^0.3.93",
- "pdfjs-dist": "^4.4.0"
+ "peerDependencies": {
+ "@types/bluebird": "*",
+ "@types/react": "*",
+ "epubjs": "*",
+ "pdfjs-dist": "*"
}
}
}
diff --git a/package.json b/package.json
index d12d442..810f73f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "zoplicate",
- "version": "3.0.5",
+ "version": "3.0.6",
"description": "Detect and manage duplicate items in Zotero.",
"config": {
"addonName": "Zoplicate",
@@ -17,7 +17,8 @@
"lint": "prettier --write . && eslint . --ext .ts --fix",
"release": "zotero-plugin release",
"test": "jest",
- "update-deps": "npm update --save"
+ "update-deps": "npm update --save",
+ "npm-check-updates": "ncu -u"
},
"repository": {
"type": "git",
@@ -30,14 +31,14 @@
},
"homepage": "https://chenglongma.com/zoplicate/",
"dependencies": {
- "zotero-plugin-toolkit": "^4.0.11"
+ "zotero-plugin-toolkit": "^4.1.1"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
- "@types/node": "^22.10.1",
- "@typescript-eslint/eslint-plugin": "^8.17.0",
- "@typescript-eslint/parser": "^8.17.0",
- "eslint": "^9.16.0",
+ "@types/node": "^22.10.5",
+ "@typescript-eslint/eslint-plugin": "^8.19.1",
+ "@typescript-eslint/parser": "^8.19.1",
+ "eslint": "^9.17.0",
"eslint-config-prettier": "^9.1.0",
"fake-indexeddb": "^6.0.0",
"jest": "^29.7.0",
@@ -46,7 +47,7 @@
"ts-node": "^10.9.2",
"typescript": "^5.7.2",
"zotero-plugin-scaffold": "^0.1.7",
- "zotero-types": "3.0.3"
+ "zotero-types": "3.1.2"
},
"eslintConfig": {
"env": {
diff --git a/src/addon.ts b/src/addon.ts
index 1330670..50aaf72 100644
--- a/src/addon.ts
+++ b/src/addon.ts
@@ -3,10 +3,12 @@ import { DialogHelper } from "zotero-plugin-toolkit/dist/helpers/dialog";
import hooks from "./hooks";
import { createZToolkit } from "./utils/ztoolkit";
import { Action } from "./utils/prefs";
+import { config } from "../package.json";
class Addon {
public data: {
alive: boolean;
+ config: typeof config;
// Env type, see build.mjs
env: "development" | "production";
database: "SQLite" | "IndexedDB";
@@ -38,6 +40,7 @@ class Addon {
constructor() {
this.data = {
alive: true,
+ config,
env: __env__,
database: "SQLite",
ztoolkit: createZToolkit(),
@@ -57,6 +60,7 @@ class Addon {
// TODO: To be implemented
this.data = {
alive: true,
+ config,
env: __env__,
database: "SQLite",
ztoolkit: createZToolkit(),
diff --git a/src/db/duplicateFinder.ts b/src/db/duplicateFinder.ts
index fa67567..8397ac4 100644
--- a/src/db/duplicateFinder.ts
+++ b/src/db/duplicateFinder.ts
@@ -120,7 +120,7 @@ export class DuplicateFinder {
}
const candidateAndClause = buildCandidateAndClause(this.candidateItemIDs);
const partialWhereClause = isbns.map(() => "REPLACE(value, '-', '') LIKE ?").join(" OR ");
- const fieldIDs: number[] = ["DOI", "ISBN", "url", "extra"].map(Zotero.ItemFields.getID);
+ const fieldIDs: (number | false)[] = ["DOI", "ISBN", "url", "extra"].map(Zotero.ItemFields.getID);
const fieldIDInClause = fieldIDs.map(() => "?").join(", ");
// Match by ISBN
const query = `SELECT DISTINCT itemID
@@ -152,8 +152,10 @@ export class DuplicateFinder {
// Should not happen
return this;
}
- const titleIDs = Zotero.ItemFields.getTypeFieldsFromBase("title");
- titleIDs.push(Zotero.ItemFields.getID("title"));
+ const titleIDs = Zotero.ItemFields.getTypeFieldsFromBase("title") as number[];
+ const titleFieldID = Zotero.ItemFields.getID("title") as number;
+
+ titleIDs.push(titleFieldID);
const candidateAndClause = buildCandidateAndClause(this.candidateItemIDs);
const partialWhereClause = titles.map(() => "TRIM(UPPER(value)) LIKE ?").join(" OR ");
@@ -226,8 +228,8 @@ export class DuplicateFinder {
const minYear = year - threshold;
const maxYear = year + threshold;
const candidateAndClause = buildCandidateAndClause(this.candidateItemIDs);
- const dateFields = Zotero.ItemFields.getTypeFieldsFromBase("date");
- dateFields.push(Zotero.ItemFields.getID("date"));
+ const dateFields = Zotero.ItemFields.getTypeFieldsFromBase("date") as number[];
+ dateFields.push(Zotero.ItemFields.getID("date") as number);
const query = `SELECT DISTINCT itemID
FROM itemDataValues
diff --git a/src/db/nonDuplicates.ts b/src/db/nonDuplicates.ts
index d98e60d..534e8b6 100644
--- a/src/db/nonDuplicates.ts
+++ b/src/db/nonDuplicates.ts
@@ -28,6 +28,7 @@ export class NonDuplicatesDB extends SQLiteDB {
libraryID INTEGER,
PRIMARY KEY (itemID, itemID2)
);`,
+ {},
);
}
@@ -118,14 +119,15 @@ export class NonDuplicatesDB extends SQLiteDB {
}
async existsNonDuplicatePair(itemID: number, itemID2: number) {
- const result = await this._db.queryAsync(
+ const result = (await this._db.queryAsync(
`SELECT EXISTS(SELECT 1
FROM ${this.tables.nonDuplicates}
WHERE (itemID = ? AND itemID2 = ?)
OR (itemID = ? AND itemID2 = ?)) AS existsResult;`,
[itemID, itemID2, itemID2, itemID],
- );
- return !!result[0].existsResult;
+ )) as { existsResult: number }[];
+
+ return result?.[0]?.existsResult ?? false;
}
async existsNonDuplicates(itemIDs: number[]) {
@@ -136,7 +138,7 @@ export class NonDuplicatesDB extends SQLiteDB {
const query = `SELECT COUNT(*) AS count
FROM ${this.tables.nonDuplicates}
WHERE (itemID, itemID2) IN (${placeholders});`;
- const result = await this._db.queryAsync(query, batch.flat());
+ const result = (await this._db.queryAsync(query, batch.flat())) as { count: number }[];
if (result[0].count !== batch.length) {
return false;
}
@@ -159,7 +161,6 @@ export class NonDuplicatesDB extends SQLiteDB {
params.push(libraryID);
}
- const rows: { itemID: number; itemID2: number }[] = await this._db.queryAsync(query, params);
- return rows;
+ return (await this._db.queryAsync(query, params)) as { itemID: number; itemID2: number }[];
}
}
diff --git a/src/hooks.ts b/src/hooks.ts
index 6020749..a578b60 100644
--- a/src/hooks.ts
+++ b/src/hooks.ts
@@ -91,6 +91,7 @@ async function onShutdown() {
await NonDuplicatesDB.instance.close();
// Remove addon object
addon.data.alive = false;
+ // @ts-ignore - Plugin instance is not typed
delete Zotero[config.addonInstance];
}
diff --git a/src/index.ts b/src/index.ts
index eb510c9..3dd098e 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -4,11 +4,13 @@ import { config } from "../package.json";
const basicTool = new BasicTool();
+// @ts-ignore - Plugin instance is not typed
if (!basicTool.getGlobal("Zotero")[config.addonInstance]) {
_globalThis.addon = new Addon();
defineGlobal("ztoolkit", () => {
return _globalThis.addon.data.ztoolkit;
});
+ // @ts-ignore - Plugin instance is not typed
Zotero[config.addonInstance] = addon;
}
diff --git a/src/modules/duplicateStats.ts b/src/modules/duplicateStats.ts
index 152cbd0..92c3150 100644
--- a/src/modules/duplicateStats.ts
+++ b/src/modules/duplicateStats.ts
@@ -17,9 +17,11 @@ export async function registerDuplicateStats() {
const patch = new ztoolkit.Patch();
patch.setData({
target: Zotero.getActiveZoteroPane().collectionsView,
+ // @ts-ignore
funcSign: "renderItem",
- // refer to https://github.com/zotero/zotero/blob/main/chrome/content/zotero/collectionTree.jsx#L274
+ // refer to https://github.com/zotero/zotero/blob/ef8de73d5ae4bc904c223845cba8467e5a405464/chrome/content/zotero/collectionTree.jsx#L286
// i.e., the `renderItem` function of collectionTree
+ // @ts-ignore
patcher:
(originalFunc: any) =>
(index: number, selection: object, oldDiv: HTMLDivElement, columns: any[]): HTMLDivElement => {
diff --git a/src/modules/merger.ts b/src/modules/merger.ts
index 340d8cc..4bf9acd 100644
--- a/src/modules/merger.ts
+++ b/src/modules/merger.ts
@@ -12,7 +12,7 @@ export async function merge(
const masterJSON = masterItem.toJSON();
const candidateJSON: {
- [field in Zotero.Item.DataType]?: string | unknown;
+ [field in _ZoteroTypes.Item.DataType]?: string | unknown;
} = otherItems.reduce((acc, obj) => ({ ...acc, ...obj.toJSON() }), {});
// Refer to https://github.com/zotero/zotero/blob/main/chrome/content/zotero/duplicatesMerge.js#L151
diff --git a/src/modules/notifier.ts b/src/modules/notifier.ts
index 300ea0a..17b64e5 100644
--- a/src/modules/notifier.ts
+++ b/src/modules/notifier.ts
@@ -45,6 +45,13 @@ export function registerNotifier() {
"tab",
]);
+ Zotero.Plugins.addObserver({
+ shutdown: ({ id }) => {
+ if (id === addon.data.config.addonID)
+ unregisterNotifier();
+ },
+ });
+
// // Unregister callback when the window closes (important to avoid a memory leak)
// window.addEventListener(
// "unload",
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index 6fde433..d465faa 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -93,7 +93,7 @@ export function normalizeString(input: string, wildcard = "%") {
* @param wildcard
*/
export function cleanCreator(
- creator: Zotero.Item.Creator,
+ creator: _ZoteroTypes.Item.Creator,
checkLength = 2,
wildcard = "%",
): {
@@ -108,7 +108,7 @@ export function cleanCreator(
}
export function cleanDOI(item: Zotero.Item): string[] {
- const possibleDOIFields: Zotero.Item.ItemField[] = ["DOI", "url"];
+ const possibleDOIFields: _ZoteroTypes.Item.ItemField[] = ["DOI", "url"];
const doiStrs = new Set();
for (const field of possibleDOIFields) {
let cleanedDOI = Zotero.Utilities.cleanDOI("" + item.getField(field));
@@ -120,7 +120,7 @@ export function cleanDOI(item: Zotero.Item): string[] {
}
export function cleanISBN(item: Zotero.Item): string[] {
- const possibleISBNFields: Zotero.Item.ItemField[] = ["DOI", "ISBN", "url"];
+ const possibleISBNFields: _ZoteroTypes.Item.ItemField[] = ["DOI", "ISBN", "url"];
let isbnString = "";
for (const field of possibleISBNFields) {
isbnString += item.getField(field) + " ";
diff --git a/src/utils/ztoolkit.ts b/src/utils/ztoolkit.ts
index 8433fde..288e79b 100644
--- a/src/utils/ztoolkit.ts
+++ b/src/utils/ztoolkit.ts
@@ -20,7 +20,9 @@ function initZToolkit(_ztoolkit: ReturnType) {
_ztoolkit.basicOptions.log.disableConsole = env === "production";
_ztoolkit.UI.basicOptions.ui.enableElementJSONLog = enableUILog;
_ztoolkit.UI.basicOptions.ui.enableElementDOMLog = enableUILog;
- _ztoolkit.basicOptions.debug.disableDebugBridgePassword = __env__ === "development";
+ // Getting basicOptions.debug will load global modules like the debug bridge.
+ // since we want to deprecate it, should avoid using it unless necessary.
+ // _ztoolkit.basicOptions.debug.disableDebugBridgePassword = __env__ === "development";
_ztoolkit.basicOptions.api.pluginID = config.addonID;
_ztoolkit.ProgressWindow.setIconURI("default", `chrome://${config.addonRef}/content/icons/preficon.svg`);
}
@@ -55,4 +57,4 @@ class MyToolkit extends BasicTool {
unregisterNonDuplicatesSection();
debug("zoplicate addon unregisterAll");
}
-}
\ No newline at end of file
+}
diff --git a/typings/duplicates.d.ts b/typings/duplicates.d.ts
new file mode 100644
index 0000000..214ef0a
--- /dev/null
+++ b/typings/duplicates.d.ts
@@ -0,0 +1,25 @@
+// https://github.com/zotero/zotero/blob/main/chrome/content/zotero/xpcom/duplicates.js
+declare namespace Zotero {
+ class Duplicates {
+ constructor(libraryID?: number);
+
+ readonly name: string;
+ readonly libraryID: number;
+
+ getSearchObject(): Promise;
+ getSetItemsByItemID(itemID: number): number[];
+ _getObjectFromID(id: number): { id: number };
+ _findDuplicates(): Promise;
+ }
+
+ class DisjointSetForest {
+ constructor();
+
+ find(x: { id: number }): { id: number, parent: { id: number }, rank: number };
+ union(x: { id: number }, y: { id: number }): void;
+ sameSet(x: { id: number }, y: { id: number }): boolean;
+ findAll(asIDs: boolean): Array<{ id: number } | number>;
+ findAllInSet(x: { id: number }, asIDs: boolean): Array<{ id: number } | number>;
+ _makeSet(x: { id: number }): void;
+ }
+}
diff --git a/typings/itemFields.d.ts b/typings/itemFields.d.ts
new file mode 100644
index 0000000..fdd0930
--- /dev/null
+++ b/typings/itemFields.d.ts
@@ -0,0 +1,24 @@
+declare namespace Zotero {
+ namespace ItemFields {
+ function getName(field: number | string): string | false;
+ function getID(field: number | string): number | false;
+ function isValidForType(fieldID: number | string, itemTypeID: number): boolean;
+ function isInteger(fieldID: number | string): boolean;
+ function getItemTypeFields(itemTypeID: number): number[];
+ function isBaseField(field: number | string): boolean;
+ function isFieldOfBase(field: number | string, baseField: number | string): boolean;
+ function getFieldIDFromTypeAndBase(itemType: number | string, baseField: number | string): number | false;
+ function getBaseIDFromTypeAndField(itemType: number | string, typeField: number | string): number | false;
+ function getTypeFieldsFromBase(baseField: number | string, asNames?: boolean): number[] | string[] | false;
+ function isAutocompleteField(field: number | string): boolean;
+ function isMultiline(field: number | string): boolean;
+ function getDirection(itemTypeID: number, field: number | string, itemLanguage?: string): 'auto' | 'ltr' | 'rtl';
+ function getAll(): { id: number, name: string }[];
+ function getLocalizedString(field: number | string): string;
+ function isCustom(fieldID: number | string): boolean;
+ function isDate(field: number | string): boolean;
+ function isLong(): boolean;
+ function init(): Promise;
+ function getBaseMappedFields(): number[];
+ }
+}
diff --git a/typings/prompt.d.ts b/typings/prompt.d.ts
new file mode 100644
index 0000000..2a889c9
--- /dev/null
+++ b/typings/prompt.d.ts
@@ -0,0 +1,34 @@
+declare namespace Zotero {
+ namespace Prompt {
+ const BUTTON_TITLE_OK: number;
+ const BUTTON_TITLE_CANCEL: number;
+ const BUTTON_TITLE_YES: number;
+ const BUTTON_TITLE_NO: number;
+ const BUTTON_TITLE_SAVE: number;
+ const BUTTON_TITLE_DONT_SAVE: number;
+ const BUTTON_TITLE_REVERT: number;
+
+ interface ConfirmOptions {
+ window?: Window | null;
+ title: string;
+ text: string;
+ button0?: string | number;
+ button1?: string | number;
+ button2?: string | number;
+ checkLabel?: string;
+ checkbox?: {};
+ defaultButton?: number;
+ buttonDelay?: boolean;
+ delayButtons?: boolean;
+ }
+
+ /**
+ * A wrapper around XPCOM's Services.prompt.confirmEx()
+ * but with a friendlier interface.
+ *
+ * @param options - The options for the confirm dialog.
+ * @returns The index of the button pressed.
+ */
+ function confirm(options: ConfirmOptions): number;
+ }
+}
diff --git a/typings/relations.d.ts b/typings/relations.d.ts
new file mode 100644
index 0000000..e46cf00
--- /dev/null
+++ b/typings/relations.d.ts
@@ -0,0 +1,48 @@
+declare namespace Zotero {
+ namespace Relations {
+ const relatedItemPredicate: _ZoteroTypes.RelationsPredicate;
+ const linkedObjectPredicate: _ZoteroTypes.RelationsPredicate;
+ const replacedItemPredicate: _ZoteroTypes.RelationsPredicate;
+
+ function init(): Promise;
+
+ function register(objectType: string, subjectID: string, predicate: string, object: string): void;
+ function unregister(objectType: string, subjectID: string, predicate: string, object: string): void;
+
+ function getByPredicateAndObject(objectType: string, predicate: string, object: string): Promise;
+ function getByObject(objectType: string, object: string): Promise<{ subject: Zotero.DataObject; predicate: string }[]>;
+
+ function copyObjectSubjectRelations(fromObject: Zotero.DataObject, toObject: Zotero.DataObject): Promise;
+ function updateUser(fromUserID: string, toUserID: string): Promise;
+ function purge(): Promise;
+ }
+ // static class Relations {
+ // static readonly relatedItemPredicate: _ZoteroTypes.RelationsPredicate;
+ // static readonly linkedObjectPredicate: _ZoteroTypes.RelationsPredicate;
+ // static readonly replacedItemPredicate: _ZoteroTypes.RelationsPredicate;
+ //
+ // private static _namespaces: { [key: string]: string };
+ // private static _types: string[];
+ // private static _subjectsByPredicateIDAndObject: { [key: string]: any };
+ // private static _subjectPredicatesByObject: { [key: string]: any };
+ //
+ // static init(): Promise;
+ //
+ // static register(objectType: string, subjectID: string, predicate: string, object: string): void;
+ // static unregister(objectType: string, subjectID: string, predicate: string, object: string): void;
+ //
+ // static getByPredicateAndObject(objectType: string, predicate: string, object: string): Promise;
+ // static getByObject(objectType: string, object: string): Promise<{ subject: Zotero.DataObject; predicate: string }[]>;
+ //
+ // static copyObjectSubjectRelations(fromObject: Zotero.DataObject, toObject: Zotero.DataObject): Promise;
+ // static updateUser(fromUserID: string, toUserID: string): Promise;
+ // static purge(): Promise;
+ //
+ // private static _getPrefixAndValue(uri: string): [string, string];
+ // }
+
+ namespace RelationPredicates {
+ function getID(predicate: string): number;
+ function getName(predicateID: number): string;
+ }
+}
diff --git a/update-beta.json b/update-beta.json
index af4ae03..375ab3a 100644
--- a/update-beta.json
+++ b/update-beta.json
@@ -3,12 +3,12 @@
"zoplicate@chenglongma.com": {
"updates": [
{
- "version": "3.0.5",
+ "version": "3.0.6",
"update_link": "https://github.com/ChenglongMa/zoplicate/releases/latest/download/zoplicate.xpi",
"applications": {
"zotero": {
"strict_min_version": "6.999",
- "strict_max_version": "7.0.*"
+ "strict_max_version": "7.*"
}
}
}
diff --git a/update.json b/update.json
index af4ae03..375ab3a 100644
--- a/update.json
+++ b/update.json
@@ -3,12 +3,12 @@
"zoplicate@chenglongma.com": {
"updates": [
{
- "version": "3.0.5",
+ "version": "3.0.6",
"update_link": "https://github.com/ChenglongMa/zoplicate/releases/latest/download/zoplicate.xpi",
"applications": {
"zotero": {
"strict_min_version": "6.999",
- "strict_max_version": "7.0.*"
+ "strict_max_version": "7.*"
}
}
}