zotero-plugin-scaffold 0.1.0-beta.2 → 0.1.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 CHANGED
@@ -1,14 +1,23 @@
1
1
  # Zotero Plugin Development Scaffold
2
2
 
3
- Working in progress.
3
+ [![NPM Version](https://img.shields.io/npm/v/zotero-plugin-scaffold)](https://www.npmjs.com/package/zotero-plugin-scaffold)
4
+ [![NPM Downloads](https://img.shields.io/npm/dm/zotero-plugin-scaffold)](https://www.npmjs.com/package/zotero-plugin-scaffold)
5
+ ![NPM Unpacked Size](https://img.shields.io/npm/unpacked-size/zotero-plugin-scaffold)
6
+ ![GitHub License](https://img.shields.io/github/license/northword/zotero-plugin-scaffold)
4
7
 
5
- Create a standalone npm package for scripts in the zotero-plugin-template repository, so that downstream developers can follow along.
8
+ 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.
6
9
 
7
- This repository serves only as a proof-of-concept for the above.
10
+ 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.
11
+
12
+ 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/northword/zotero-plugin-scaffold/network/dependents).
13
+
14
+ For best practices regarding this package, please refer to [zotero-plugin-template](https://github.com/windingwind/zotero-plugin-template).
8
15
 
9
16
  ## Using in a blank project
10
17
 
11
- > WIP: Not yet implemented
18
+ <details>
19
+
20
+ <summary>WIP: Not yet implemented</summary>
12
21
 
13
22
  ```bash
14
23
  # npm
@@ -17,6 +26,8 @@ npx zotero-plugin create
17
26
  pnpm dlx zotero-plugin create
18
27
  ```
19
28
 
29
+ </details>
30
+
20
31
  ## Using in an existing project
21
32
 
22
33
  ### 01. Install
@@ -49,28 +60,25 @@ pnpm link ../zotero-plugin-scaffold
49
60
 
50
61
  ### 02. Create a config file
51
62
 
52
- The configuration file needs to be stored in the following location. If the configuration file is not found, an error will be thrown.
63
+ The configuration file needs to be stored in the following location.
53
64
 
54
65
  ```bash
55
66
  zotero-plugin.config.ts # also avaliable in *.js *.mjs *.cjs *.ts
56
67
  ```
57
68
 
58
- You can import `defineConfig` in js module to get type hints. If no value is specified for an optional property, the default value will be used.
69
+ You can import helper `defineConfig` to get type hints. If no value is specified for an optional property, the default value will be used.
59
70
 
60
71
  ```ts
61
72
  import { defineConfig } from "zotero-plugin-scaffold";
62
73
 
63
74
  export default defineConfig({
64
- name: pkg.config.addonName,
65
- id: pkg.config.addonID,
66
- namespace: pkg.config.addonRef,
75
+ name: "the plugin name",
76
+ id: "the plugin id",
77
+ namespace: "the plugin namespace",
67
78
  build: {
68
79
  esbuildOptions: [
69
80
  {
70
81
  entryPoints: ["src/index.ts"],
71
- define: {
72
- __env__: `"${process.env.NODE_ENV}"`,
73
- },
74
82
  bundle: true,
75
83
  target: "firefox115",
76
84
  },
@@ -93,8 +101,7 @@ NOTE: Do not check-in this file to the repository!
93
101
 
94
102
  ```ini
95
103
  # The path of the Zotero binary file.
96
- # The path delimiter should be escaped as `\\` for win32.
97
- # The path is `*/Zotero.app/Contents/MacOS/zotero` for MacOS.
104
+ # The path is `*/Zotero.app/Contents/MacOS/zotero` for macOS.
98
105
  ZOTERO_PLUGIN_ZOTERO_BIN_PATH = /path/to/zotero.exe
99
106
 
100
107
  # The path of the profile used for development.
@@ -144,13 +151,14 @@ cd zotero-plugin-scaffold/
144
151
  pnpm install
145
152
 
146
153
  # Development Mode
147
- # This command creates a js runtime using jiti, and the modified code does not need to be built again.
154
+ # This command creates a typescript runtime using jiti,
155
+ # and the modified code does not need to be built again.
148
156
  pnpm run dev
149
157
 
150
158
  # Build
151
159
  pnpm run build
152
160
 
153
- # Lint and Prettier
161
+ # ES Lint
154
162
  pnpm run lint:fix
155
163
  ```
156
164
 
package/dist/cli.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { exit, env } from 'node:process';
3
- import { Command } from 'commander';
3
+ import { Command } from '@commander-js/extra-typings';
4
4
  import updateNotifier from 'update-notifier';
5
- import { L as Log, C as Config, B as Build, S as Serve, R as Release } from './shared/zotero-plugin-scaffold.125bc4ce.mjs';
5
+ import { L as Log, C as Config, B as Build, S as Serve, R as Release } from './shared/zotero-plugin-scaffold.06668c10.mjs';
6
6
  import 'node:path';
7
7
  import 'c12';
8
8
  import 'fs-extra';
@@ -25,7 +25,7 @@ import 'chokidar';
25
25
  import 'node:fs';
26
26
 
27
27
  const name = "zotero-plugin-scaffold";
28
- const version = "0.1.0-beta.2";
28
+ const version = "0.1.0";
29
29
 
30
30
  const logger = new Log();
31
31
  async function main() {
@@ -34,35 +34,38 @@ async function main() {
34
34
  (_a = env).NODE_ENV ?? (_a.NODE_ENV = "development");
35
35
  const cli = new Command();
36
36
  cli.version(version).usage("<command> [options]");
37
- cli.command("build").description("Build the plugin.").option("--dev", "Builds the plugin in dev mode.").option("--dist <dir>", "The relative path for the new output directory (default: build)").action(async (options) => {
37
+ cli.command("build").description("Build the plugin").option("--dev", "Builds the plugin in dev mode").option("--dist <dir>", "The relative path for the new output directory (default: build)").action((options) => {
38
38
  env.NODE_ENV = options.dev ? "development" : "production";
39
- const config = await Config.loadConfig({
39
+ Config.loadConfig({
40
40
  dist: options.dist
41
- });
42
- new Build(config).run();
41
+ }).then((ctx) => new Build(ctx).run());
43
42
  });
44
- cli.command("serve").description("Start development server.").action(async (_options) => {
45
- const config = await Config.loadConfig({});
46
- new Serve(config).run();
43
+ cli.command("serve").alias("dev").description("Start development server").action((_options) => {
44
+ Config.loadConfig({}).then((ctx) => new Serve(ctx).run());
47
45
  });
48
- cli.command("create").description("Create the plugin template.").action((_options) => {
46
+ cli.command("create").description("Create the plugin template").action((_options) => {
49
47
  logger.error("The create not yet implemented");
50
48
  });
51
- cli.command("release").description("Release.").action(async (_options) => {
49
+ cli.command("release").description("Release the plugin").argument("[version]", "Target version: major, minor, patch, pre*, or specify version").option("--preid <preid>", "ID for prerelease").option("-y, --yes", "Skip confirmation").action(async (version2, options) => {
52
50
  env.NODE_ENV = "production";
53
- const config = await Config.loadConfig({});
54
- new Release(config).run();
51
+ Config.loadConfig({
52
+ release: {
53
+ bumpp: {
54
+ release: version2,
55
+ preid: options.preid,
56
+ confirm: !options.yes
57
+ }
58
+ }
59
+ }).then((ctx) => new Release(ctx).run());
55
60
  });
56
61
  cli.arguments("<command>").action((cmd) => {
57
62
  cli.outputHelp();
58
- logger.error(`Unknown command name=${cmd}.`);
63
+ logger.error(`Unknown command name "${cmd}".`);
59
64
  });
60
65
  cli.parse();
61
66
  }
62
67
  main().catch((err) => {
63
- logger.newLine();
64
68
  logger.error(err);
65
- logger.newLine();
66
69
  exit(1);
67
70
  });
68
71
 
package/dist/index.d.mts CHANGED
@@ -106,67 +106,97 @@ interface Config$1 {
106
106
  */
107
107
  dist: string;
108
108
  /**
109
- * The name of plugin
109
+ * The name of plugin.
110
110
  *
111
- * 插件名
111
+ * 插件名。
112
112
  *
113
113
  * @default package-json.name
114
114
  *
115
115
  */
116
116
  name: string;
117
117
  /**
118
- * The ID of plugin
118
+ * The ID of plugin.
119
119
  *
120
- * 插件 ID
120
+ * Usually in the form of an email address or UUID.
121
+ *
122
+ * 插件 ID。
123
+ *
124
+ * 通常是邮箱地址或UUID的形式。
121
125
  *
122
126
  * @default package-json.name
123
127
  */
124
128
  id: string;
125
129
  /**
126
- * namespace of plugin
130
+ * namespace of plugin.
131
+ *
132
+ * This attribute is also used to prevent plugin conflicts,
133
+ * it may be used for plugin HTML element ids, preference prefixes,
134
+ * fluent filename prefixes, fluent message prefixes, etc.
135
+ *
136
+ * Unlike the plugin id, this value should be HTML ID and Fluent Message compliant,
137
+ * i.e.: contain at least one character and only letters and dashes.
127
138
  *
128
- * 插件命名空间
139
+ * 插件命名空间。
140
+ *
141
+ * 这个属性也用于防止插件冲突,它可能被用于插件的 HTML 元素 id,
142
+ * 首选项前缀,Fluent 文件名前缀、Fluent message 前缀等。
143
+ *
144
+ * 与插件 ID 不同的是,这个值应是符合 HTML ID 和 Fluent Message 规范的,
145
+ * 即:至少包含一个字符,仅包含字母和短横线。
129
146
  *
130
147
  * @default kebabCase(name)
131
148
  */
132
149
  namespace: string;
133
150
  /**
134
- * XPI filename
151
+ * XPI filename.
152
+ *
153
+ * XPI 文件名。
135
154
  *
136
155
  * @default kebabCase(name)
137
156
  */
138
157
  xpiName: string;
139
158
  /**
140
- * XPI 文件的地址
159
+ * The download link of XPI.
160
+ *
161
+ * XPI 文件的地址。
141
162
  *
142
163
  * @default `https://github.com/{{owner}}/{{repo}}/release/download/v{{version}}/{{xpiName}}.xpi`
143
164
  */
144
165
  xpiDownloadLink: string;
145
166
  /**
146
- * update.json 文件的地址
167
+ * The uri of update.json.
168
+ *
169
+ * update.json 文件的地址。
147
170
  *
148
171
  * @default `https://github.com/{{owner}}/{{repo}}/release/download/release/update.json`
149
172
  */
150
173
  updateURL: string;
151
174
  /**
152
- * 构建所需的配置
175
+ * Configurations required to run the build.
176
+ *
177
+ * 构建所需的配置。
153
178
  */
154
179
  build: BuildConfig;
155
180
  /**
156
- * serve 所需的配置
181
+ * Configurations required to run the server.
182
+ *
183
+ * serve 所需的配置。
157
184
  */
158
185
  server: ServerConfig;
159
186
  /**
160
- * @todo Use addonLint package to lint XPI
187
+ * @todo Use addonLint package to lint XPI.
161
188
  */
162
189
  addonLint: object;
163
190
  /**
164
- * 发布相关配置
191
+ * Configurations required to run the release.
165
192
  *
193
+ * 发布相关配置。
166
194
  */
167
195
  release: ReleaseConfig;
168
196
  /**
169
- * Log level
197
+ * Level of the log.
198
+ *
199
+ * 日志等级。
170
200
  *
171
201
  * @default "info"
172
202
  */
@@ -174,7 +204,11 @@ interface Config$1 {
174
204
  }
175
205
  interface BuildConfig {
176
206
  /**
177
- * glob list of static assets
207
+ * The static assets.
208
+ *
209
+ * - Typically includes icons, ftl files, 3rd party JavaScript files, CSS files, XHTML files, etc.
210
+ * - is an array of `glob` modes and supports negation modes.
211
+ * - Do not add an entire directory unless it has no files to exclude.
178
212
  *
179
213
  * 静态资源文件。
180
214
  *
@@ -190,7 +224,10 @@ interface BuildConfig {
190
224
  */
191
225
  assets: string | string[];
192
226
  /**
193
- * placeholders to replace in static assets
227
+ * The placeholders to replace in static assets.
228
+ *
229
+ * - At build time, scaffolding uses the key of the placeholder to build the regular pattern `/__${key}__/g` and replaces matches with `value`.
230
+ * - Replacement happens for all files under `assets`.
194
231
  *
195
232
  * 静态资源文本占位符。
196
233
  *
@@ -202,45 +239,53 @@ interface BuildConfig {
202
239
  };
203
240
  fluent: {
204
241
  /**
205
- * 为所有 FTL 文件添加插件前缀以避免冲突
242
+ * Add plugin namespace prefixes to all FTL files to avoid conflicts.
206
243
  *
207
- * 默认前缀为 `${namespace}-`
244
+ * The default prefix is `${namespace}-`.
245
+ *
246
+ * 为所有 FTL 文件添加插件前缀以避免冲突。
247
+ *
248
+ * 默认前缀为 `${namespace}-`。
208
249
  *
209
250
  * @default true
210
251
  */
211
252
  prefixLocaleFiles: boolean;
212
253
  /**
213
- * 为所有 FTL message 添加插件前缀以避免冲突
254
+ * Add plugin namespace prefixes to all FTL messages to avoid conflicts.
255
+ *
256
+ * The default prefix is `${namespace}-`.
257
+ *
258
+ * 为所有 FTL message 添加插件前缀以避免冲突。
214
259
  *
215
- * 默认前缀为 `${namespace}-`
260
+ * 默认前缀为 `${namespace}-`。
216
261
  *
217
262
  * @default true
218
263
  */
219
264
  prefixFluentMessages: boolean;
220
265
  };
221
266
  /**
222
- * The config of esbuild
267
+ * Configurations of esbuild.
223
268
  *
224
- * esbuild 配置
269
+ * esbuild 配置。
225
270
  *
226
271
  * @default []
227
272
  *
228
273
  */
229
274
  esbuildOptions: BuildOptions[];
230
275
  /**
231
- * Make manifest.json
276
+ * Make manifest.json.
232
277
  *
233
278
  */
234
279
  makeManifest: {
235
280
  /**
236
281
  * 是否自动管理 manifest.json。
237
- * 如果此项为 false,则开发者应自行准备 manifest.json
282
+ * 如果此项为 false,则开发者应自行准备 manifest.json。
238
283
  *
239
284
  * @default true
240
285
  */
241
286
  enable: boolean;
242
287
  /**
243
- * template of manifest
288
+ * template of manifest.
244
289
  *
245
290
  * @deprecated
246
291
  *
@@ -270,26 +315,33 @@ interface BuildConfig {
270
315
  template: Manifest;
271
316
  };
272
317
  /**
273
- * Make update manifest
318
+ * Make update manifest.
274
319
  *
275
- * 生成 `update.json`
320
+ * 生成 `update.json`。
276
321
  *
277
322
  */
278
323
  makeUpdateJson: {
279
324
  /**
280
- * Enable make update.json
325
+ * Historical update data.
281
326
  *
282
- * @default true
283
- */
284
- enable: boolean | "only-production";
285
- /**
286
- * 已有的更新数据
327
+ * This can be useful if you need to distribute different plugin versions
328
+ * for different versions of Zotero.
329
+ *
330
+ * 已有的更新数据。
331
+ *
332
+ * 如果你需要为不同版本的 Zotero 分发不同的插件版本,这可能会很有用。
333
+ *
334
+ * @see {@link https://www.zotero.org/support/dev/zotero_7_for_developers#updaterdf_updatesjson | Zotero 7 for developers}
335
+ * @see {@link https://extensionworkshop.com/documentation/manage/updating-your-extension/ | Updating your extension}
336
+ * @see {@link https://zotero-chinese.com/plugin-dev-guide/reference/update | 更新清单 (In chinese)}
287
337
  *
288
338
  * @default []
289
339
  */
290
340
  updates: UpdateJSON["addons"][string]["updates"];
291
341
  /**
292
- * 是否向 update.json 中写入 xpi 文件的 hash
342
+ * Whether or not to write the hash of the xpi file to update.json.
343
+ *
344
+ * 是否向 update.json 中写入 xpi 文件的 hash。
293
345
  *
294
346
  * @default true
295
347
  */
@@ -314,18 +366,24 @@ interface BuildHooks {
314
366
  }
315
367
  interface ServerConfig {
316
368
  /**
317
- * Open devtool on Zotero start
369
+ * Open devtool on Zotero start.
370
+ *
371
+ * 在 Zotero 启动时打开 devtool。
318
372
  *
319
373
  * @default true
320
374
  */
321
375
  devtools: boolean;
322
376
  /**
323
- * 启动 Zotero 时附加的命令行参数
377
+ * Additional command line arguments when starting Zotero.
378
+ *
379
+ * 启动 Zotero 时附加的命令行参数。
324
380
  *
325
- * @default ["--purgecaches"]
381
+ * @default []
326
382
  */
327
383
  startArgs: string[];
328
384
  /**
385
+ * Install the plugin as a Proxy File mode.
386
+ *
329
387
  * 以 Proxy File 方式载入插件
330
388
  *
331
389
  * @default false
@@ -346,7 +404,9 @@ interface ServeHooks {
346
404
  }
347
405
  interface ReleaseConfig {
348
406
  /**
349
- * Config of bumpp
407
+ * Configurations of bumpp
408
+ *
409
+ * bumpp 包的部分配置。
350
410
  */
351
411
  bumpp: {
352
412
  /**
@@ -355,13 +415,27 @@ interface ReleaseConfig {
355
415
  * - A release type (e.g. "major", "minor", "patch", "prerelease", etc.)
356
416
  * - "prompt" to prompt the user for the version number
357
417
  *
358
- * @default "prompt".
418
+ * In general, it is recommended to set this to “prompt”.
419
+ * If you need a command that always releases a certain type,
420
+ * you can override this option on the command line.
421
+ *
422
+ * 发布的类型,可以是以下其中之一:
423
+ *
424
+ * - 版本类型(如 “major”、“minor”、“patch”、“prerelease”等)
425
+ * - “prompt” 以选择版本号
426
+ *
427
+ * 通常来说,建议将此项设置为“prompt”。
428
+ * 如果需要一个始终发布某类型的命令,可以在命令行中覆盖该选项。
429
+ *
430
+ * @default "prompt"
359
431
  */
360
432
  release: string;
361
433
  /**
362
434
  * The prerelease type (e.g. "alpha", "beta", "next").
363
435
  *
364
- * @default "beta".
436
+ * 预发布的类型,如 alpha,beta,next 等。
437
+ *
438
+ * @default "beta"
365
439
  */
366
440
  preid: string;
367
441
  /**
@@ -371,6 +445,11 @@ interface ReleaseConfig {
371
445
  * If the message string does _not_ contain any `%s` placeholders,
372
446
  * then the new version number will be appended to the message.
373
447
  *
448
+ * 提交说明模板。
449
+ *
450
+ * 模板中的 `%s` 占位符将被替换为新版本号。
451
+ * 如果模板中不包含任何 `%s` 占位符,则新版本号将附加到模板末端。
452
+ *
374
453
  * @default "chore(publish): release %s"
375
454
  */
376
455
  commit: string;
@@ -381,6 +460,11 @@ interface ReleaseConfig {
381
460
  * If the tag string does _not_ contain any `%s` placeholders,
382
461
  * then the new version number will be appended to the tag.
383
462
  *
463
+ * 标签模板。
464
+ *
465
+ * 模板中的 `%s` 占位符将被替换为新版本号。
466
+ * 如果模板中不包含任何 `%s` 占位符,则新版本号将附加到模板末端。
467
+ *
384
468
  * @default "v%s"
385
469
  */
386
470
  tag: string;
@@ -388,38 +472,56 @@ interface ReleaseConfig {
388
472
  * Indicates whether the git commit should include ALL files (`git commit --all`)
389
473
  * rather than just the files that were modified by `versionBump()`.
390
474
  *
391
- * Defaults to `false`.
475
+ * 表示 git 提交是否应包括所有文件(`git commit --all`),
476
+ * 而不是只包含被 `versionBump()` 修改过的文件。
477
+ *
478
+ * @default false
479
+ *
392
480
  */
393
- all?: boolean;
481
+ all: boolean;
394
482
  /**
395
- * Prompt for confirmation
483
+ * Prompt for confirmation.
484
+ *
485
+ * 选择版本号后是否要求二次确认。
396
486
  *
397
487
  * @default true
398
488
  */
399
- confirm?: boolean;
489
+ confirm: boolean;
400
490
  /**
401
491
  * Indicates whether to bypass git commit hooks (`git commit --no-verify`).
402
492
  *
403
- * Defaults to `false`.
493
+ * 表示是否绕过 git commit hooks(`git commit --no-verify` )。
494
+ *
495
+ * @default false
404
496
  */
405
- noVerify?: boolean;
497
+ noVerify: boolean;
406
498
  /**
407
- * Excute additional command after bumping and before commiting
499
+ * Excute additional command after bumping and before commiting.
500
+ *
501
+ * 在提升版本号之后,提交之前运行的额外命令。
502
+ *
503
+ * @default "npm run build"
504
+ *
408
505
  */
409
- execute?: string;
506
+ execute: string;
410
507
  };
411
508
  /**
412
- * Changelog
509
+ * Changelog.
510
+ *
511
+ * If a string is provided, it must be command line
512
+ * and with changelog output to stdout.
513
+ *
514
+ * 如果提供了字符串,则必须为命令行,且变更日志输出到stdout
413
515
  *
414
516
  * @default "git log {{previousTag}}..{{currentTag}}"
415
517
  */
416
518
  changelog: string | ((ctx: Context) => string);
417
519
  /**
418
- * Release to GitHub
520
+ * Release to GitHub.
419
521
  */
420
522
  github: {
421
523
  /**
422
- * Enable release to GitHub
524
+ * Enable release to GitHub.
423
525
  *
424
526
  * Include uploading XPI asset to GitHub release and all following steps.
425
527
  *
@@ -432,13 +534,19 @@ interface ReleaseConfig {
432
534
  */
433
535
  enable: "ci" | "local" | "always" | "false";
434
536
  /**
435
- * Upload update.json to release
537
+ * Upload update.json to release.
538
+ *
539
+ * This is the tagName of the release when the value is a string.
540
+ *
541
+ * 将 update.json 上传到指定的 GitHub release。
542
+ *
543
+ * 当值为字符串时,其为 release 的tagName。
436
544
  *
437
545
  * @default "release"
438
546
  */
439
547
  updater: string | false;
440
548
  /**
441
- * Comment to issues and prs inlcuded in release
549
+ * Comment to issues and prs inlcuded in release.
442
550
  *
443
551
  * @todo Not implemented yet
444
552
  *
package/dist/index.d.ts CHANGED
@@ -106,67 +106,97 @@ interface Config$1 {
106
106
  */
107
107
  dist: string;
108
108
  /**
109
- * The name of plugin
109
+ * The name of plugin.
110
110
  *
111
- * 插件名
111
+ * 插件名。
112
112
  *
113
113
  * @default package-json.name
114
114
  *
115
115
  */
116
116
  name: string;
117
117
  /**
118
- * The ID of plugin
118
+ * The ID of plugin.
119
119
  *
120
- * 插件 ID
120
+ * Usually in the form of an email address or UUID.
121
+ *
122
+ * 插件 ID。
123
+ *
124
+ * 通常是邮箱地址或UUID的形式。
121
125
  *
122
126
  * @default package-json.name
123
127
  */
124
128
  id: string;
125
129
  /**
126
- * namespace of plugin
130
+ * namespace of plugin.
131
+ *
132
+ * This attribute is also used to prevent plugin conflicts,
133
+ * it may be used for plugin HTML element ids, preference prefixes,
134
+ * fluent filename prefixes, fluent message prefixes, etc.
135
+ *
136
+ * Unlike the plugin id, this value should be HTML ID and Fluent Message compliant,
137
+ * i.e.: contain at least one character and only letters and dashes.
127
138
  *
128
- * 插件命名空间
139
+ * 插件命名空间。
140
+ *
141
+ * 这个属性也用于防止插件冲突,它可能被用于插件的 HTML 元素 id,
142
+ * 首选项前缀,Fluent 文件名前缀、Fluent message 前缀等。
143
+ *
144
+ * 与插件 ID 不同的是,这个值应是符合 HTML ID 和 Fluent Message 规范的,
145
+ * 即:至少包含一个字符,仅包含字母和短横线。
129
146
  *
130
147
  * @default kebabCase(name)
131
148
  */
132
149
  namespace: string;
133
150
  /**
134
- * XPI filename
151
+ * XPI filename.
152
+ *
153
+ * XPI 文件名。
135
154
  *
136
155
  * @default kebabCase(name)
137
156
  */
138
157
  xpiName: string;
139
158
  /**
140
- * XPI 文件的地址
159
+ * The download link of XPI.
160
+ *
161
+ * XPI 文件的地址。
141
162
  *
142
163
  * @default `https://github.com/{{owner}}/{{repo}}/release/download/v{{version}}/{{xpiName}}.xpi`
143
164
  */
144
165
  xpiDownloadLink: string;
145
166
  /**
146
- * update.json 文件的地址
167
+ * The uri of update.json.
168
+ *
169
+ * update.json 文件的地址。
147
170
  *
148
171
  * @default `https://github.com/{{owner}}/{{repo}}/release/download/release/update.json`
149
172
  */
150
173
  updateURL: string;
151
174
  /**
152
- * 构建所需的配置
175
+ * Configurations required to run the build.
176
+ *
177
+ * 构建所需的配置。
153
178
  */
154
179
  build: BuildConfig;
155
180
  /**
156
- * serve 所需的配置
181
+ * Configurations required to run the server.
182
+ *
183
+ * serve 所需的配置。
157
184
  */
158
185
  server: ServerConfig;
159
186
  /**
160
- * @todo Use addonLint package to lint XPI
187
+ * @todo Use addonLint package to lint XPI.
161
188
  */
162
189
  addonLint: object;
163
190
  /**
164
- * 发布相关配置
191
+ * Configurations required to run the release.
165
192
  *
193
+ * 发布相关配置。
166
194
  */
167
195
  release: ReleaseConfig;
168
196
  /**
169
- * Log level
197
+ * Level of the log.
198
+ *
199
+ * 日志等级。
170
200
  *
171
201
  * @default "info"
172
202
  */
@@ -174,7 +204,11 @@ interface Config$1 {
174
204
  }
175
205
  interface BuildConfig {
176
206
  /**
177
- * glob list of static assets
207
+ * The static assets.
208
+ *
209
+ * - Typically includes icons, ftl files, 3rd party JavaScript files, CSS files, XHTML files, etc.
210
+ * - is an array of `glob` modes and supports negation modes.
211
+ * - Do not add an entire directory unless it has no files to exclude.
178
212
  *
179
213
  * 静态资源文件。
180
214
  *
@@ -190,7 +224,10 @@ interface BuildConfig {
190
224
  */
191
225
  assets: string | string[];
192
226
  /**
193
- * placeholders to replace in static assets
227
+ * The placeholders to replace in static assets.
228
+ *
229
+ * - At build time, scaffolding uses the key of the placeholder to build the regular pattern `/__${key}__/g` and replaces matches with `value`.
230
+ * - Replacement happens for all files under `assets`.
194
231
  *
195
232
  * 静态资源文本占位符。
196
233
  *
@@ -202,45 +239,53 @@ interface BuildConfig {
202
239
  };
203
240
  fluent: {
204
241
  /**
205
- * 为所有 FTL 文件添加插件前缀以避免冲突
242
+ * Add plugin namespace prefixes to all FTL files to avoid conflicts.
206
243
  *
207
- * 默认前缀为 `${namespace}-`
244
+ * The default prefix is `${namespace}-`.
245
+ *
246
+ * 为所有 FTL 文件添加插件前缀以避免冲突。
247
+ *
248
+ * 默认前缀为 `${namespace}-`。
208
249
  *
209
250
  * @default true
210
251
  */
211
252
  prefixLocaleFiles: boolean;
212
253
  /**
213
- * 为所有 FTL message 添加插件前缀以避免冲突
254
+ * Add plugin namespace prefixes to all FTL messages to avoid conflicts.
255
+ *
256
+ * The default prefix is `${namespace}-`.
257
+ *
258
+ * 为所有 FTL message 添加插件前缀以避免冲突。
214
259
  *
215
- * 默认前缀为 `${namespace}-`
260
+ * 默认前缀为 `${namespace}-`。
216
261
  *
217
262
  * @default true
218
263
  */
219
264
  prefixFluentMessages: boolean;
220
265
  };
221
266
  /**
222
- * The config of esbuild
267
+ * Configurations of esbuild.
223
268
  *
224
- * esbuild 配置
269
+ * esbuild 配置。
225
270
  *
226
271
  * @default []
227
272
  *
228
273
  */
229
274
  esbuildOptions: BuildOptions[];
230
275
  /**
231
- * Make manifest.json
276
+ * Make manifest.json.
232
277
  *
233
278
  */
234
279
  makeManifest: {
235
280
  /**
236
281
  * 是否自动管理 manifest.json。
237
- * 如果此项为 false,则开发者应自行准备 manifest.json
282
+ * 如果此项为 false,则开发者应自行准备 manifest.json。
238
283
  *
239
284
  * @default true
240
285
  */
241
286
  enable: boolean;
242
287
  /**
243
- * template of manifest
288
+ * template of manifest.
244
289
  *
245
290
  * @deprecated
246
291
  *
@@ -270,26 +315,33 @@ interface BuildConfig {
270
315
  template: Manifest;
271
316
  };
272
317
  /**
273
- * Make update manifest
318
+ * Make update manifest.
274
319
  *
275
- * 生成 `update.json`
320
+ * 生成 `update.json`。
276
321
  *
277
322
  */
278
323
  makeUpdateJson: {
279
324
  /**
280
- * Enable make update.json
325
+ * Historical update data.
281
326
  *
282
- * @default true
283
- */
284
- enable: boolean | "only-production";
285
- /**
286
- * 已有的更新数据
327
+ * This can be useful if you need to distribute different plugin versions
328
+ * for different versions of Zotero.
329
+ *
330
+ * 已有的更新数据。
331
+ *
332
+ * 如果你需要为不同版本的 Zotero 分发不同的插件版本,这可能会很有用。
333
+ *
334
+ * @see {@link https://www.zotero.org/support/dev/zotero_7_for_developers#updaterdf_updatesjson | Zotero 7 for developers}
335
+ * @see {@link https://extensionworkshop.com/documentation/manage/updating-your-extension/ | Updating your extension}
336
+ * @see {@link https://zotero-chinese.com/plugin-dev-guide/reference/update | 更新清单 (In chinese)}
287
337
  *
288
338
  * @default []
289
339
  */
290
340
  updates: UpdateJSON["addons"][string]["updates"];
291
341
  /**
292
- * 是否向 update.json 中写入 xpi 文件的 hash
342
+ * Whether or not to write the hash of the xpi file to update.json.
343
+ *
344
+ * 是否向 update.json 中写入 xpi 文件的 hash。
293
345
  *
294
346
  * @default true
295
347
  */
@@ -314,18 +366,24 @@ interface BuildHooks {
314
366
  }
315
367
  interface ServerConfig {
316
368
  /**
317
- * Open devtool on Zotero start
369
+ * Open devtool on Zotero start.
370
+ *
371
+ * 在 Zotero 启动时打开 devtool。
318
372
  *
319
373
  * @default true
320
374
  */
321
375
  devtools: boolean;
322
376
  /**
323
- * 启动 Zotero 时附加的命令行参数
377
+ * Additional command line arguments when starting Zotero.
378
+ *
379
+ * 启动 Zotero 时附加的命令行参数。
324
380
  *
325
- * @default ["--purgecaches"]
381
+ * @default []
326
382
  */
327
383
  startArgs: string[];
328
384
  /**
385
+ * Install the plugin as a Proxy File mode.
386
+ *
329
387
  * 以 Proxy File 方式载入插件
330
388
  *
331
389
  * @default false
@@ -346,7 +404,9 @@ interface ServeHooks {
346
404
  }
347
405
  interface ReleaseConfig {
348
406
  /**
349
- * Config of bumpp
407
+ * Configurations of bumpp
408
+ *
409
+ * bumpp 包的部分配置。
350
410
  */
351
411
  bumpp: {
352
412
  /**
@@ -355,13 +415,27 @@ interface ReleaseConfig {
355
415
  * - A release type (e.g. "major", "minor", "patch", "prerelease", etc.)
356
416
  * - "prompt" to prompt the user for the version number
357
417
  *
358
- * @default "prompt".
418
+ * In general, it is recommended to set this to “prompt”.
419
+ * If you need a command that always releases a certain type,
420
+ * you can override this option on the command line.
421
+ *
422
+ * 发布的类型,可以是以下其中之一:
423
+ *
424
+ * - 版本类型(如 “major”、“minor”、“patch”、“prerelease”等)
425
+ * - “prompt” 以选择版本号
426
+ *
427
+ * 通常来说,建议将此项设置为“prompt”。
428
+ * 如果需要一个始终发布某类型的命令,可以在命令行中覆盖该选项。
429
+ *
430
+ * @default "prompt"
359
431
  */
360
432
  release: string;
361
433
  /**
362
434
  * The prerelease type (e.g. "alpha", "beta", "next").
363
435
  *
364
- * @default "beta".
436
+ * 预发布的类型,如 alpha,beta,next 等。
437
+ *
438
+ * @default "beta"
365
439
  */
366
440
  preid: string;
367
441
  /**
@@ -371,6 +445,11 @@ interface ReleaseConfig {
371
445
  * If the message string does _not_ contain any `%s` placeholders,
372
446
  * then the new version number will be appended to the message.
373
447
  *
448
+ * 提交说明模板。
449
+ *
450
+ * 模板中的 `%s` 占位符将被替换为新版本号。
451
+ * 如果模板中不包含任何 `%s` 占位符,则新版本号将附加到模板末端。
452
+ *
374
453
  * @default "chore(publish): release %s"
375
454
  */
376
455
  commit: string;
@@ -381,6 +460,11 @@ interface ReleaseConfig {
381
460
  * If the tag string does _not_ contain any `%s` placeholders,
382
461
  * then the new version number will be appended to the tag.
383
462
  *
463
+ * 标签模板。
464
+ *
465
+ * 模板中的 `%s` 占位符将被替换为新版本号。
466
+ * 如果模板中不包含任何 `%s` 占位符,则新版本号将附加到模板末端。
467
+ *
384
468
  * @default "v%s"
385
469
  */
386
470
  tag: string;
@@ -388,38 +472,56 @@ interface ReleaseConfig {
388
472
  * Indicates whether the git commit should include ALL files (`git commit --all`)
389
473
  * rather than just the files that were modified by `versionBump()`.
390
474
  *
391
- * Defaults to `false`.
475
+ * 表示 git 提交是否应包括所有文件(`git commit --all`),
476
+ * 而不是只包含被 `versionBump()` 修改过的文件。
477
+ *
478
+ * @default false
479
+ *
392
480
  */
393
- all?: boolean;
481
+ all: boolean;
394
482
  /**
395
- * Prompt for confirmation
483
+ * Prompt for confirmation.
484
+ *
485
+ * 选择版本号后是否要求二次确认。
396
486
  *
397
487
  * @default true
398
488
  */
399
- confirm?: boolean;
489
+ confirm: boolean;
400
490
  /**
401
491
  * Indicates whether to bypass git commit hooks (`git commit --no-verify`).
402
492
  *
403
- * Defaults to `false`.
493
+ * 表示是否绕过 git commit hooks(`git commit --no-verify` )。
494
+ *
495
+ * @default false
404
496
  */
405
- noVerify?: boolean;
497
+ noVerify: boolean;
406
498
  /**
407
- * Excute additional command after bumping and before commiting
499
+ * Excute additional command after bumping and before commiting.
500
+ *
501
+ * 在提升版本号之后,提交之前运行的额外命令。
502
+ *
503
+ * @default "npm run build"
504
+ *
408
505
  */
409
- execute?: string;
506
+ execute: string;
410
507
  };
411
508
  /**
412
- * Changelog
509
+ * Changelog.
510
+ *
511
+ * If a string is provided, it must be command line
512
+ * and with changelog output to stdout.
513
+ *
514
+ * 如果提供了字符串,则必须为命令行,且变更日志输出到stdout
413
515
  *
414
516
  * @default "git log {{previousTag}}..{{currentTag}}"
415
517
  */
416
518
  changelog: string | ((ctx: Context) => string);
417
519
  /**
418
- * Release to GitHub
520
+ * Release to GitHub.
419
521
  */
420
522
  github: {
421
523
  /**
422
- * Enable release to GitHub
524
+ * Enable release to GitHub.
423
525
  *
424
526
  * Include uploading XPI asset to GitHub release and all following steps.
425
527
  *
@@ -432,13 +534,19 @@ interface ReleaseConfig {
432
534
  */
433
535
  enable: "ci" | "local" | "always" | "false";
434
536
  /**
435
- * Upload update.json to release
537
+ * Upload update.json to release.
538
+ *
539
+ * This is the tagName of the release when the value is a string.
540
+ *
541
+ * 将 update.json 上传到指定的 GitHub release。
542
+ *
543
+ * 当值为字符串时,其为 release 的tagName。
436
544
  *
437
545
  * @default "release"
438
546
  */
439
547
  updater: string | false;
440
548
  /**
441
- * Comment to issues and prs inlcuded in release
549
+ * Comment to issues and prs inlcuded in release.
442
550
  *
443
551
  * @todo Not implemented yet
444
552
  *
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { B as Build, C as Config, R as Release, S as Serve, d as defineConfig } from './shared/zotero-plugin-scaffold.125bc4ce.mjs';
1
+ export { B as Build, C as Config, R as Release, S as Serve, d as defineConfig } from './shared/zotero-plugin-scaffold.06668c10.mjs';
2
2
  import 'node:path';
3
3
  import 'c12';
4
4
  import 'fs-extra';
@@ -62,7 +62,9 @@ ${arg.stack}`;
62
62
  console.log(...args);
63
63
  }
64
64
  error(...args) {
65
+ this.newLine();
65
66
  this.logArgs(4 /* error */, chalk.bgRed(" ERROR "), ...args);
67
+ this.newLine();
66
68
  }
67
69
  warn(...args) {
68
70
  this.newLine();
@@ -260,7 +262,6 @@ const defaultConfig = {
260
262
  }
261
263
  },
262
264
  makeUpdateJson: {
263
- enable: true,
264
265
  updates: [],
265
266
  hash: true
266
267
  },
@@ -276,11 +277,12 @@ const defaultConfig = {
276
277
  release: {
277
278
  bumpp: {
278
279
  release: "prompt",
279
- confirm: true,
280
280
  preid: "beta",
281
- // execute: "npm run build",
281
+ confirm: true,
282
+ execute: "",
282
283
  all: false,
283
284
  commit: "chore(publish): release v%s",
285
+ noVerify: false,
284
286
  tag: "v%s"
285
287
  },
286
288
  changelog: "",
@@ -874,8 +876,8 @@ class Release extends Base {
874
876
  const isGitHubEnabled = this.isEnabled(release.github.enable);
875
877
  const isGiteeEnabled = this.isEnabled(release.gitee.enable);
876
878
  const isPublishNeeded = isGitHubEnabled || isGiteeEnabled;
877
- if (isBumpNeeded && isPublishNeeded && !!release.bumpp.execute) {
878
- this.logger.warn("The current release needs to run the build after bumping the version number, please configure the build script in config.release.bumpp.execute.");
879
+ if (isPublishNeeded && !release.bumpp.execute) {
880
+ this.logger.warn(`The current release needs to run the build after bumping the version number, please configure the build script in 'config.release.bumpp.execute'${isBumpNeeded ? "" : " or run build before run release"}.`);
879
881
  (_a = this.ctx.release.bumpp).execute || (_a.execute = "npm run build");
880
882
  }
881
883
  this.logger.debug("Release config: ", this.ctx.release);
@@ -911,19 +913,25 @@ class Release extends Base {
911
913
  const currentTagIndex = tags.indexOf(currentTag);
912
914
  if (currentTagIndex === -1)
913
915
  throw new Error(`Tag "${currentTag}" not found.`);
916
+ let previousTagIndex = currentTagIndex - 1;
917
+ let previousTag;
914
918
  if (currentTagIndex === 0) {
915
- return execSync(`git log ${currentTag} --pretty=format:"* %s (%h)"`).toString().trim();
919
+ previousTag = false;
920
+ } else if (currentTag.includes("-")) {
921
+ previousTag = tags[previousTagIndex];
916
922
  } else {
917
- let previousTagIndex = currentTagIndex - 1;
918
923
  while (previousTagIndex >= 0 && tags[previousTagIndex].includes("-")) {
919
924
  previousTagIndex--;
920
925
  }
921
- if (previousTagIndex < 0) {
922
- return execSync(`git log ${currentTag} --pretty=format:"* %s (%h)"`).toString().trim();
923
- }
924
- const previousTag = tags[previousTagIndex];
925
- return execSync(`git log ${previousTag}..${currentTag} --pretty=format:"* %s (%h)"`).toString().trim();
926
+ if (previousTagIndex < 0)
927
+ previousTag = false;
928
+ else
929
+ previousTag = tags[previousTagIndex];
926
930
  }
931
+ if (previousTag)
932
+ return execSync(`git log --pretty=format:"* %s (%h)" ${previousTag}..${currentTag}`).toString().trim();
933
+ else
934
+ return execSync(`git log --pretty=format:"* %s (%h)" ${currentTag}`).toString().trim();
927
935
  }
928
936
  getFilteredChangelog(rawLog, commitMessage) {
929
937
  const filterRegex = new RegExp(escapeRegExp(commitMessage));
@@ -946,7 +954,8 @@ class Release extends Base {
946
954
  changelog = this.getFilteredChangelog(rawLog, resolvedCommitMessage);
947
955
  }
948
956
  this.logger.debug(`Got changelog:
949
- `, changelog, "\n");
957
+ ${changelog}
958
+ `);
950
959
  return changelog;
951
960
  }
952
961
  isEnabled(enable) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zotero-plugin-scaffold",
3
3
  "type": "module",
4
- "version": "0.1.0-beta.2",
4
+ "version": "0.1.0",
5
5
  "description": "A scaffold for Zotero plugin development.",
6
6
  "author": "northword",
7
7
  "license": "AGPL-3.0-or-later",
@@ -51,34 +51,35 @@
51
51
  "doc": "docs"
52
52
  },
53
53
  "dependencies": {
54
- "@inquirer/prompts": "5.3.6",
55
- "bumpp": "9.4.1",
56
- "c12": "1.11.1",
57
- "chalk": "5.3.0",
58
- "chokidar": "3.6.0",
59
- "commander": "12.1.0",
60
- "conventional-changelog": "6.0.0",
54
+ "@commander-js/extra-typings": "^12.1.0",
55
+ "@inquirer/prompts": "^5.3.8",
56
+ "bumpp": "^9.5.2",
57
+ "c12": "^1.11.1",
58
+ "chalk": "^5.3.0",
59
+ "chokidar": "^3.6.0",
60
+ "commander": "^12.1.0",
61
+ "conventional-changelog": "^6.0.0",
61
62
  "es-toolkit": "^1.16.0",
62
- "esbuild": "0.23.0",
63
- "fs-extra": "11.2.0",
63
+ "esbuild": "^0.23.1",
64
+ "fs-extra": "^11.2.0",
64
65
  "globby": "^14.0.2",
65
- "hookable": "5.5.3",
66
- "mime": "4.0.4",
67
- "octokit": "4.0.2",
68
- "replace-in-file": "8.1.0",
69
- "std-env": "3.7.0",
70
- "update-notifier": "7.1.0",
71
- "web-ext": "8.2.0"
66
+ "hookable": "^5.5.3",
67
+ "mime": "^4.0.4",
68
+ "octokit": "^4.0.2",
69
+ "replace-in-file": "^8.1.0",
70
+ "std-env": "^3.7.0",
71
+ "update-notifier": "^7.2.0",
72
+ "web-ext": "^8.2.0"
72
73
  },
73
74
  "devDependencies": {
74
- "@antfu/eslint-config": "^2.23.0",
75
- "@types/fs-extra": "11.0.4",
76
- "@types/node": "20.14.13",
77
- "@types/update-notifier": "6.0.8",
78
- "eslint": "9.8.0",
75
+ "@antfu/eslint-config": "^2.27.1",
76
+ "@types/fs-extra": "^11.0.4",
77
+ "@types/node": "^20.16.1",
78
+ "@types/update-notifier": "^6.0.8",
79
+ "eslint": "^9.9.1",
79
80
  "eslint-plugin-format": "^0.1.2",
80
- "typescript": "5.5.4",
81
- "unbuild": "2.0.0"
81
+ "typescript": "^5.5.4",
82
+ "unbuild": "^2.0.0"
82
83
  },
83
84
  "scripts": {
84
85
  "dev": "unbuild --stub",