zotero-plugin-scaffold 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/shared/{zotero-plugin-scaffold.BLTrbfUc.mjs → zotero-plugin-scaffold.8gLns8GX.mjs} +74 -14
- package/dist/shared/{zotero-plugin-scaffold.CIruZpuO.d.mts → zotero-plugin-scaffold.fkuivpCE.d.mts} +18 -4
- package/package.json +16 -16
package/README.md
CHANGED
|
@@ -3,26 +3,26 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/zotero-plugin-scaffold)
|
|
4
4
|
[](https://www.npmjs.com/package/zotero-plugin-scaffold)
|
|
5
5
|

|
|
6
|
-

|
|
7
7
|
[](https://github.com/antfu/eslint-config)
|
|
8
8
|
|
|
9
9
|
This is an npm package designed to assist in the development of Zotero plugins. It provides features such as compiling plugins, starting Zotero and installing plugins from source code, reloading plugins when the source code changes, and releasing plugins, and so on.
|
|
10
10
|
|
|
11
11
|
Initially, the code of this package was part of the [zotero-plugin-template](https://github.com/windingwind/zotero-plugin-template) repository. To allow downstream developers to easily stay up-to-date, we have abstracted these scripts into a standalone npm package.
|
|
12
12
|
|
|
13
|
-
This project is under active development, and some APIs may change. However, it is ready for production and has been [used in several projects](https://github.com/
|
|
13
|
+
This project is under active development, and some APIs may change. However, it is ready for production and has been [used in several projects](https://github.com/zotero-plugin-dev/zotero-plugin-scaffold/network/dependents).
|
|
14
14
|
|
|
15
15
|
For best practices regarding this package, please refer to [zotero-plugin-template](https://github.com/windingwind/zotero-plugin-template).
|
|
16
16
|
|
|
17
17
|
## Documentation
|
|
18
18
|
|
|
19
|
-
[Read the Docs to Learn More](https://
|
|
19
|
+
[Read the Docs to Learn More](https://zotero-plugin-dev.github.io/zotero-plugin-scaffold).
|
|
20
20
|
|
|
21
21
|
## Contributing
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
# Git Clone
|
|
25
|
-
git clone https://github.com/
|
|
25
|
+
git clone https://github.com/zotero-plugin-dev/zotero-plugin-scaffold.git
|
|
26
26
|
cd zotero-plugin-scaffold/
|
|
27
27
|
|
|
28
28
|
# Install deps
|
|
@@ -36,7 +36,7 @@ pnpm run dev
|
|
|
36
36
|
|
|
37
37
|
# link local scaffold to your plugin
|
|
38
38
|
cd your-plugin-work-dir/
|
|
39
|
-
pnpm link ../zotero-plugin-scaffold/
|
|
39
|
+
pnpm link ../zotero-plugin-scaffold/
|
|
40
40
|
cd zotero-plugin-scaffold/
|
|
41
41
|
```
|
|
42
42
|
|
|
@@ -60,4 +60,4 @@ GNU Affero General Public License Version 3.
|
|
|
60
60
|
|
|
61
61
|
This project references the design and code of the [Zotero Plugin Template](https://github.com/windingwind/zotero-plugin-template).
|
|
62
62
|
|
|
63
|
-
This project would not be possible without the support of the [open source community](https://github.com/
|
|
63
|
+
This project would not be possible without the support of the [open source community](https://github.com/zotero-plugin-dev/zotero-plugin-scaffold/network/dependencies).
|
package/dist/cli.d.mts
CHANGED
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
-
import { E as ExitSignals, C as Config, B as Build, S as Serve, T as Test, R as Release } from './shared/zotero-plugin-scaffold.
|
|
3
|
+
import { E as ExitSignals, C as Config, B as Build, S as Serve, T as Test, R as Release } from './shared/zotero-plugin-scaffold.8gLns8GX.mjs';
|
|
4
4
|
import { readFile } from 'node:fs/promises';
|
|
5
5
|
import { pathExists } from 'fs-extra';
|
|
6
6
|
import { l as logger } from './shared/zotero-plugin-scaffold.CzBjWbS8.mjs';
|
|
@@ -36,7 +36,7 @@ import 'node:http';
|
|
|
36
36
|
import 'node:readline';
|
|
37
37
|
|
|
38
38
|
const name = "zotero-plugin-scaffold";
|
|
39
|
-
const version = "0.
|
|
39
|
+
const version = "0.8.0";
|
|
40
40
|
const pkg = {
|
|
41
41
|
name: name,
|
|
42
42
|
version: version};
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { U as UserConfig, O as OverrideConfig, C as Context, B as Base } from './shared/zotero-plugin-scaffold.
|
|
1
|
+
import { U as UserConfig, O as OverrideConfig, C as Context, B as Base } from './shared/zotero-plugin-scaffold.fkuivpCE.mjs';
|
|
2
2
|
import 'hookable';
|
|
3
3
|
import 'esbuild';
|
|
4
4
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { B as Build, C as Config, R as Release, S as Serve, T as Test, d as defineConfig } from './shared/zotero-plugin-scaffold.
|
|
1
|
+
export { B as Build, C as Config, R as Release, S as Serve, T as Test, d as defineConfig } from './shared/zotero-plugin-scaffold.8gLns8GX.mjs';
|
|
2
2
|
import 'c12';
|
|
3
3
|
import 'es-toolkit';
|
|
4
4
|
import 'fs-extra/esm';
|
package/dist/shared/{zotero-plugin-scaffold.BLTrbfUc.mjs → zotero-plugin-scaffold.8gLns8GX.mjs}
RENAMED
|
@@ -87,6 +87,7 @@ function resolveConfig$1(config) {
|
|
|
87
87
|
}
|
|
88
88
|
const defaultConfig = {
|
|
89
89
|
source: "src",
|
|
90
|
+
watchIgnore: [],
|
|
90
91
|
dist: ".scaffold/build",
|
|
91
92
|
name: "",
|
|
92
93
|
id: "",
|
|
@@ -2454,18 +2455,19 @@ function resolveModuleURL(input, options) {
|
|
|
2454
2455
|
}
|
|
2455
2456
|
}
|
|
2456
2457
|
const conditionsSet = options?.conditions ? new Set(options.conditions) : DEFAULT_CONDITIONS_SET;
|
|
2458
|
+
const target = specifier || url.href;
|
|
2457
2459
|
const bases = _normalizeBases(options?.from);
|
|
2458
2460
|
const suffixes = options?.suffixes || [""];
|
|
2459
2461
|
const extensions = options?.extensions ? ["", ...options.extensions] : [""];
|
|
2460
2462
|
let resolved;
|
|
2461
2463
|
for (const base of bases) {
|
|
2462
2464
|
for (const suffix of suffixes) {
|
|
2465
|
+
let name = _join(target, suffix);
|
|
2466
|
+
if (name === ".") {
|
|
2467
|
+
name += "/.";
|
|
2468
|
+
}
|
|
2463
2469
|
for (const extension of extensions) {
|
|
2464
|
-
resolved = _tryModuleResolve(
|
|
2465
|
-
_join(specifier || url.href, suffix) + extension,
|
|
2466
|
-
base,
|
|
2467
|
-
conditionsSet
|
|
2468
|
-
);
|
|
2470
|
+
resolved = _tryModuleResolve(name + extension, base, conditionsSet);
|
|
2469
2471
|
if (resolved) {
|
|
2470
2472
|
break;
|
|
2471
2473
|
}
|
|
@@ -2529,7 +2531,7 @@ function _normalizeBase(input) {
|
|
|
2529
2531
|
if (!input) {
|
|
2530
2532
|
return [];
|
|
2531
2533
|
}
|
|
2532
|
-
if (input
|
|
2534
|
+
if (_isURL(input)) {
|
|
2533
2535
|
return [input];
|
|
2534
2536
|
}
|
|
2535
2537
|
if (typeof input !== "string") {
|
|
@@ -2572,6 +2574,9 @@ function _join(a, b) {
|
|
|
2572
2574
|
function _normalizeWinPath(path) {
|
|
2573
2575
|
return path.replace(/\\/g, "/").replace(/^[a-z]:\//, (r) => r.toUpperCase());
|
|
2574
2576
|
}
|
|
2577
|
+
function _isURL(input) {
|
|
2578
|
+
return input instanceof URL || input?.constructor?.name === "URL";
|
|
2579
|
+
}
|
|
2575
2580
|
function _parseInput(input) {
|
|
2576
2581
|
if (typeof input === "string") {
|
|
2577
2582
|
if (input.startsWith("file:")) {
|
|
@@ -2589,7 +2594,7 @@ function _parseInput(input) {
|
|
|
2589
2594
|
}
|
|
2590
2595
|
return { specifier: input };
|
|
2591
2596
|
}
|
|
2592
|
-
if (input
|
|
2597
|
+
if (_isURL(input)) {
|
|
2593
2598
|
if (input.protocol === "file:") {
|
|
2594
2599
|
return { url: input, absolutePath: fileURLToPath(input) };
|
|
2595
2600
|
}
|
|
@@ -2732,6 +2737,52 @@ async function getGitDiff(from, to = "HEAD", cwd) {
|
|
|
2732
2737
|
return r2;
|
|
2733
2738
|
});
|
|
2734
2739
|
}
|
|
2740
|
+
function parseCommits(commits, config) {
|
|
2741
|
+
return commits.map((commit) => parseGitCommit(commit, config)).filter(Boolean);
|
|
2742
|
+
}
|
|
2743
|
+
const ConventionalCommitRegex = /(?<emoji>:.+:|(\uD83C[\uDF00-\uDFFF])|(\uD83D[\uDC00-\uDE4F\uDE80-\uDEFF])|[\u2600-\u2B55])?( *)?(?<type>[a-z]+)(\((?<scope>.+)\))?(?<breaking>!)?: (?<description>.+)/i;
|
|
2744
|
+
const CoAuthoredByRegex = /co-authored-by:\s*(?<name>.+)(<(?<email>.+)>)/gim;
|
|
2745
|
+
const PullRequestRE = /\([ a-z]*(#\d+)\s*\)/gm;
|
|
2746
|
+
const IssueRE = /(#\d+)/gm;
|
|
2747
|
+
function parseGitCommit(commit, config) {
|
|
2748
|
+
const match = commit.message.match(ConventionalCommitRegex);
|
|
2749
|
+
if (!match) {
|
|
2750
|
+
return null;
|
|
2751
|
+
}
|
|
2752
|
+
const type = match.groups.type;
|
|
2753
|
+
const hasBreakingBody = /breaking change:/i.test(commit.body);
|
|
2754
|
+
let scope = match.groups.scope || "";
|
|
2755
|
+
scope = config.scopeMap[scope] || scope;
|
|
2756
|
+
const isBreaking = Boolean(match.groups.breaking || hasBreakingBody);
|
|
2757
|
+
let description = match.groups.description;
|
|
2758
|
+
const references = [];
|
|
2759
|
+
for (const m of description.matchAll(PullRequestRE)) {
|
|
2760
|
+
references.push({ type: "pull-request", value: m[1] });
|
|
2761
|
+
}
|
|
2762
|
+
for (const m of description.matchAll(IssueRE)) {
|
|
2763
|
+
if (!references.some((i) => i.value === m[1])) {
|
|
2764
|
+
references.push({ type: "issue", value: m[1] });
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
references.push({ value: commit.shortHash, type: "hash" });
|
|
2768
|
+
description = description.replace(PullRequestRE, "").trim();
|
|
2769
|
+
const authors = [commit.author];
|
|
2770
|
+
for (const match2 of commit.body.matchAll(CoAuthoredByRegex)) {
|
|
2771
|
+
authors.push({
|
|
2772
|
+
name: (match2.groups.name || "").trim(),
|
|
2773
|
+
email: (match2.groups.email || "").trim()
|
|
2774
|
+
});
|
|
2775
|
+
}
|
|
2776
|
+
return {
|
|
2777
|
+
...commit,
|
|
2778
|
+
authors,
|
|
2779
|
+
description,
|
|
2780
|
+
type,
|
|
2781
|
+
scope,
|
|
2782
|
+
references,
|
|
2783
|
+
isBreaking
|
|
2784
|
+
};
|
|
2785
|
+
}
|
|
2735
2786
|
|
|
2736
2787
|
const providerToRefSpec = {
|
|
2737
2788
|
github: { "pull-request": "pull", hash: "commit", issue: "issues" },
|
|
@@ -2883,9 +2934,9 @@ async function generateMarkDown(commits, config) {
|
|
|
2883
2934
|
const _email = [...i.email].find(
|
|
2884
2935
|
(e) => !e.includes("noreply.github.com")
|
|
2885
2936
|
);
|
|
2886
|
-
const email = config.hideAuthorEmail !== true && _email ?
|
|
2887
|
-
const github = i.github ? `([@${i.github}](https://github.com/${i.github}))` : "";
|
|
2888
|
-
return `- ${i.name}
|
|
2937
|
+
const email = config.hideAuthorEmail !== true && _email ? ` <${_email}>` : "";
|
|
2938
|
+
const github = i.github ? ` ([@${i.github}](https://github.com/${i.github}))` : "";
|
|
2939
|
+
return `- ${i.name}${github || email || ""}`;
|
|
2889
2940
|
})
|
|
2890
2941
|
);
|
|
2891
2942
|
}
|
|
@@ -3272,10 +3323,17 @@ ${changelog}
|
|
|
3272
3323
|
}
|
|
3273
3324
|
}
|
|
3274
3325
|
|
|
3275
|
-
function watch(source, event) {
|
|
3326
|
+
function watch(source, ignore, event) {
|
|
3276
3327
|
const watcher = chokidar.watch(source, {
|
|
3277
|
-
ignored:
|
|
3278
|
-
|
|
3328
|
+
ignored: [
|
|
3329
|
+
/(^|[/\\])\../,
|
|
3330
|
+
// ignore dotfiles
|
|
3331
|
+
/[\\/]\.git[\\/]/,
|
|
3332
|
+
/[\\/]node_modules[\\/]/,
|
|
3333
|
+
...toArray(ignore)
|
|
3334
|
+
],
|
|
3335
|
+
ignoreInitial: true,
|
|
3336
|
+
ignorePermissionErrors: true,
|
|
3279
3337
|
persistent: true
|
|
3280
3338
|
});
|
|
3281
3339
|
const onChangeDebounced = safeDebounce(event.onChange);
|
|
@@ -4102,9 +4160,10 @@ class Serve extends Base {
|
|
|
4102
4160
|
* watch source dir and build when file changed
|
|
4103
4161
|
*/
|
|
4104
4162
|
async watch() {
|
|
4105
|
-
const { source } = this.ctx;
|
|
4163
|
+
const { source, watchIgnore } = this.ctx;
|
|
4106
4164
|
watch(
|
|
4107
4165
|
source,
|
|
4166
|
+
watchIgnore,
|
|
4108
4167
|
{
|
|
4109
4168
|
onReady: async () => {
|
|
4110
4169
|
await this.ctx.hooks.callHook("serve:ready", this.ctx);
|
|
@@ -4800,6 +4859,7 @@ class Test extends Base {
|
|
|
4800
4859
|
}
|
|
4801
4860
|
watch(
|
|
4802
4861
|
[this.ctx.source, this.ctx.test.entries].flat(),
|
|
4862
|
+
this.ctx.watchIgnore,
|
|
4803
4863
|
{
|
|
4804
4864
|
onChange: async (path) => {
|
|
4805
4865
|
if (isSource(path)) {
|
package/dist/shared/{zotero-plugin-scaffold.CIruZpuO.d.mts → zotero-plugin-scaffold.fkuivpCE.d.mts}
RENAMED
|
@@ -125,17 +125,31 @@ interface UpdateJSON {
|
|
|
125
125
|
|
|
126
126
|
interface Config {
|
|
127
127
|
/**
|
|
128
|
-
*
|
|
128
|
+
* Source root directory or directories for the plugin.
|
|
129
129
|
*
|
|
130
|
-
*
|
|
130
|
+
* These paths are:
|
|
131
|
+
* - Watched during development to trigger rebuilds on changes.
|
|
132
|
+
* - Used to remove the top-level asset directory (e.g. `assets/`) during build,
|
|
133
|
+
* so that only its contents are copied directly to the output root.
|
|
131
134
|
*
|
|
132
|
-
*
|
|
135
|
+
* 插件的源码根目录(可为字符串或字符串数组)。
|
|
133
136
|
*
|
|
134
|
-
*
|
|
137
|
+
* 用于以下两个目的:
|
|
138
|
+
* - 在开发模式下监听这些目录,以便在文件变更时触发重建;
|
|
139
|
+
* - 在构建阶段中,用于识别 assets 所在的顶层目录,以移除该目录本身,仅将其内容复制到输出目录的根部。
|
|
135
140
|
*
|
|
141
|
+
* @example ["src", "addon"]
|
|
136
142
|
* @default "src"
|
|
137
143
|
*/
|
|
138
144
|
source: string | string[];
|
|
145
|
+
/**
|
|
146
|
+
* The files to ignore when watching.
|
|
147
|
+
*
|
|
148
|
+
* 忽略的监听文件。
|
|
149
|
+
*
|
|
150
|
+
* @default []
|
|
151
|
+
*/
|
|
152
|
+
watchIgnore: string | string[] | RegExp | RegExp[];
|
|
139
153
|
/**
|
|
140
154
|
* The build directories.
|
|
141
155
|
*
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zotero-plugin-scaffold",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.0",
|
|
5
5
|
"description": "A scaffold for Zotero plugin development.",
|
|
6
6
|
"author": "northword",
|
|
7
7
|
"license": "AGPL-3.0-or-later",
|
|
@@ -55,14 +55,14 @@
|
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@fluent/syntax": "^0.19.0",
|
|
58
|
-
"@swc/core": "^1.
|
|
58
|
+
"@swc/core": "^1.13.3",
|
|
59
59
|
"adm-zip": "^0.5.16",
|
|
60
|
-
"bumpp": "^10.
|
|
61
|
-
"c12": "^3.0
|
|
60
|
+
"bumpp": "^10.2.1",
|
|
61
|
+
"c12": "^3.2.0",
|
|
62
62
|
"chokidar": "^4.0.3",
|
|
63
63
|
"commander": "^14.0.0",
|
|
64
|
-
"es-toolkit": "^1.39.
|
|
65
|
-
"esbuild": "^0.25.
|
|
64
|
+
"es-toolkit": "^1.39.8",
|
|
65
|
+
"esbuild": "^0.25.8",
|
|
66
66
|
"fs-extra": "^11.3.0",
|
|
67
67
|
"hookable": "^5.5.3",
|
|
68
68
|
"octokit": "^5.0.3",
|
|
@@ -72,22 +72,22 @@
|
|
|
72
72
|
"xvfb-ts": "^1.1.0"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@antfu/eslint-config": "^
|
|
75
|
+
"@antfu/eslint-config": "^5.0.0",
|
|
76
76
|
"@commander-js/extra-typings": "^14.0.0",
|
|
77
77
|
"@types/adm-zip": "^0.5.7",
|
|
78
78
|
"@types/fs-extra": "^11.0.4",
|
|
79
|
-
"@types/node": "^22.
|
|
80
|
-
"bumpp": "^10.
|
|
81
|
-
"changelogen": "^0.6.
|
|
82
|
-
"eslint": "^9.
|
|
79
|
+
"@types/node": "^22.17.0",
|
|
80
|
+
"bumpp": "^10.2.1",
|
|
81
|
+
"changelogen": "^0.6.2",
|
|
82
|
+
"eslint": "^9.32.0",
|
|
83
83
|
"eslint-plugin-format": "^1.0.1",
|
|
84
84
|
"husky": "^9.1.7",
|
|
85
|
-
"lint-staged": "^16.1.
|
|
85
|
+
"lint-staged": "^16.1.2",
|
|
86
86
|
"node-style-text": "^0.0.8",
|
|
87
|
-
"tsx": "^4.20.
|
|
88
|
-
"typescript": "^5.
|
|
89
|
-
"unbuild": "^3.
|
|
90
|
-
"vitest": "^3.2.
|
|
87
|
+
"tsx": "^4.20.3",
|
|
88
|
+
"typescript": "^5.9.2",
|
|
89
|
+
"unbuild": "^3.6.0",
|
|
90
|
+
"vitest": "^3.2.4"
|
|
91
91
|
},
|
|
92
92
|
"workspaces": [
|
|
93
93
|
"src",
|