zotero-plugin-scaffold 0.2.0-beta.8 → 0.2.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,167 +1,10 @@
1
1
  # Zotero Plugin Development Scaffold
2
2
 
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)
7
- [![code style](https://antfu.me/badge-code-style.svg)](https://github.com/antfu/eslint-config)
3
+ Delivering a modern and elegant development experience for Zotero plugins.
8
4
 
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.
5
+ ## Documentation
10
6
 
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
-
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/northword/zotero-plugin-scaffold/network/dependents).
14
-
15
- For best practices regarding this package, please refer to [zotero-plugin-template](https://github.com/windingwind/zotero-plugin-template).
16
-
17
- ## Using in a blank project
18
-
19
- <details>
20
-
21
- <summary>WIP: Not yet implemented</summary>
22
-
23
- ```bash
24
- # npm
25
- npx zotero-plugin create
26
- # pnpm
27
- pnpm dlx zotero-plugin create
28
- ```
29
-
30
- </details>
31
-
32
- ## Using in an existing project
33
-
34
- ### 01. Install
35
-
36
- #### From NPM
37
-
38
- ```bash
39
- npm install -D zotero-plugin-scaffold
40
-
41
- yarn add -D zotero-plugin-scaffold
42
-
43
- pnpm add -D zotero-plugin-scaffold
44
- ```
45
-
46
- #### From source code
47
-
48
- ```bash
49
- # clone this repo
50
- git clone https://github.com/northword/zotero-plugin-scaffold.git zotero-plugin-scaffold/
51
- cd zotero-plugin-scaffold/
52
-
53
- # build
54
- pnpm install
55
- pnpm build # or pnpm dev
56
-
57
- # npm link
58
- cd your-plugin-work-dir/
59
- pnpm link ../zotero-plugin-scaffold
60
- ```
61
-
62
- ### 02. Create a config file
63
-
64
- The configuration file needs to be stored in the following location.
65
-
66
- ```bash
67
- zotero-plugin.config.ts # also avaliable in *.js *.mjs *.cjs *.ts
68
- ```
69
-
70
- You can import helper `defineConfig` to get type hints. If no value is specified for an optional property, the default value will be used.
71
-
72
- ```ts
73
- import { defineConfig } from "zotero-plugin-scaffold";
74
-
75
- export default defineConfig({
76
- name: "the plugin name",
77
- id: "the plugin id",
78
- namespace: "the plugin namespace",
79
- build: {
80
- esbuildOptions: [
81
- {
82
- entryPoints: ["src/index.ts"],
83
- bundle: true,
84
- target: "firefox115",
85
- },
86
- ],
87
- },
88
- });
89
- ```
90
-
91
- Full config please refrence in [src/types](./src/types/index.ts).
92
-
93
- ### 03. Create a env file
94
-
95
- This file defines Zotero's runtime configuration such as binary paths, profile paths, and environment variables required for Node scripts to run.
96
-
97
- NOTE: Do not check-in this file to the repository!
98
-
99
- ```bash
100
- .env
101
- ```
102
-
103
- ```ini
104
- # The path of the Zotero binary file.
105
- # The path is `*/Zotero.app/Contents/MacOS/zotero` for macOS.
106
- ZOTERO_PLUGIN_ZOTERO_BIN_PATH = /path/to/zotero.exe
107
-
108
- # The path of the profile used for development.
109
- # Start the profile manager by `/path/to/zotero.exe -p` to create a profile for development.
110
- # @see https://www.zotero.org/support/kb/profile_directory
111
- ZOTERO_PLUGIN_PROFILE_PATH = /path/to/profile
112
- ```
113
-
114
- ### 04. Add scripts to package.json
115
-
116
- ```json
117
- {
118
- "scripts": {
119
- "start": "zotero-plugin serve",
120
- "build": "zotero-plugin build",
121
- "release": "zotero-plugin release"
122
- }
123
- }
124
- ```
125
-
126
- ### 05. Run
127
-
128
- ```bash
129
- pnpm run start
130
- pnpm run build
131
- ```
132
-
133
- ## Using in NodeJS code
134
-
135
- ```ts
136
- import { Build, Config } from "zotero-plugin-scaffold";
137
-
138
- const config = await Config.loadConfig();
139
-
140
- const Builder = new Build(config);
141
- await Builder.run();
142
- ```
143
-
144
- ## Contributing
145
-
146
- ```bash
147
- # Git Clone
148
- git clone https://github.com/northword/zotero-plugin-scaffold.git zotero-plugin-scaffold
149
- cd zotero-plugin-scaffold/
150
-
151
- # Install deps
152
- pnpm install
153
-
154
- # Development Mode
155
- # This command creates a typescript runtime using jiti,
156
- # and the modified code does not need to be built again.
157
- pnpm run dev
158
-
159
- # Build
160
- pnpm run build
161
-
162
- # ES Lint
163
- pnpm run lint:fix
164
- ```
7
+ [Read the Docs to Learn More](https://northword.github.io/zotero-plugin-scaffold).
165
8
 
166
9
  ## License
167
10
 
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import cli from "../dist/cli.mjs";
4
+
5
+ cli();
@@ -1,22 +1,21 @@
1
1
  import { readFile, stat } from 'node:fs/promises';
2
- import { join, basename } from 'node:path';
3
- import { env } from 'node:process';
4
- import mime from 'mime';
2
+ import { extname, join, basename } from 'node:path';
3
+ import process from 'node:process';
5
4
  import { Octokit } from 'octokit';
6
5
  import { globSync, glob } from 'tinyglobby';
7
6
  import { isCI } from 'std-env';
8
- import { a as Base } from '../shared/zotero-plugin-scaffold.dc0b582a.mjs';
7
+ import { B as Base } from '../shared/zotero-plugin-scaffold.DoUCzsKc.mjs';
9
8
  import 'c12';
10
9
  import 'es-toolkit';
11
10
  import 'fs-extra/esm';
12
11
  import 'hookable';
13
12
  import 'node:readline';
14
13
  import 'chalk';
15
- import '../shared/zotero-plugin-scaffold.77c9802c.mjs';
14
+ import '../shared/zotero-plugin-scaffold.v8dJZZ-v.mjs';
15
+ import 'node:fs';
16
16
  import 'adm-zip';
17
17
  import 'esbuild';
18
18
  import 'node:crypto';
19
- import 'node:fs';
20
19
  import 'node:child_process';
21
20
  import 'bumpp';
22
21
  import 'chokidar';
@@ -27,16 +26,23 @@ import 'node:events';
27
26
  import 'node:http';
28
27
  import 'xvfb-ts';
29
28
 
30
- var __defProp$1 = Object.defineProperty;
31
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
32
- var __publicField$1 = (obj, key, value) => {
33
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
34
- return value;
29
+ const mimeTypes = {
30
+ "application/json": ["json"],
31
+ "application/x-xpinstall": ["xpi"]
35
32
  };
33
+ function getMimeTypeByFileName(filename) {
34
+ const ext = extname(filename);
35
+ for (const type in mimeTypes) {
36
+ if (mimeTypes[type].includes(ext))
37
+ return type;
38
+ }
39
+ return undefined;
40
+ }
41
+
36
42
  class ReleaseBase extends Base {
43
+ isCI;
37
44
  constructor(ctx) {
38
45
  super(ctx);
39
- __publicField$1(this, "isCI");
40
46
  this.isCI = isCI;
41
47
  }
42
48
  checkFiles() {
@@ -47,16 +53,10 @@ class ReleaseBase extends Base {
47
53
  }
48
54
  }
49
55
 
50
- var __defProp = Object.defineProperty;
51
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
52
- var __publicField = (obj, key, value) => {
53
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
54
- return value;
55
- };
56
56
  class GitHub extends ReleaseBase {
57
+ client;
57
58
  constructor(ctx) {
58
59
  super(ctx);
59
- __publicField(this, "client");
60
60
  this.client = this.getClient();
61
61
  }
62
62
  async run() {
@@ -91,7 +91,7 @@ class GitHub extends ReleaseBase {
91
91
  tag
92
92
  }).catch((e) => {
93
93
  this.logger.debug(`Release with tag ${tag} not found. ${e}`);
94
- return void 0;
94
+ return undefined;
95
95
  }).then((res) => {
96
96
  if (res && res.status === 200) {
97
97
  this.logger.debug(`Found release with tag "${tag}", id=${res.data.id}.`);
@@ -118,7 +118,7 @@ class GitHub extends ReleaseBase {
118
118
  release_id: releaseID,
119
119
  data: await readFile(asset),
120
120
  headers: {
121
- "content-type": mime.getType(asset) || "application/octet-stream",
121
+ "content-type": getMimeTypeByFileName(asset) || "application/octet-stream",
122
122
  "content-length": (await stat(asset)).size
123
123
  },
124
124
  name: basename(asset)
@@ -168,7 +168,7 @@ class GitHub extends ReleaseBase {
168
168
  release_id: release.id,
169
169
  name: "Release Manifest",
170
170
  body: `This release is used to host \`update.json\`, please do not delete or modify it!
171
- Updated in UTC ${( new Date()).toISOString()} for version ${version}`,
171
+ Updated in UTC ${(/* @__PURE__ */ new Date()).toISOString()} for version ${version}`,
172
172
  prerelease: true,
173
173
  make_latest: "false"
174
174
  });
@@ -180,10 +180,10 @@ class GitHub extends ReleaseBase {
180
180
  return releaseNote(this.ctx);
181
181
  }
182
182
  getClient() {
183
- if (!env.GITHUB_TOKEN)
183
+ if (!process.env.GITHUB_TOKEN)
184
184
  throw new Error("No GITHUB_TOKEN.");
185
185
  const client = new Octokit({
186
- auth: env.GITHUB_TOKEN,
186
+ auth: process.env.GITHUB_TOKEN,
187
187
  userAgent: "zotero-plugin-scaffold"
188
188
  });
189
189
  return client;
package/dist/cli.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- declare function main(): Promise<void>;
1
+ declare function run(): Promise<void>;
2
2
 
3
- export { main as default };
3
+ export { run as default };
package/dist/cli.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- declare function main(): Promise<void>;
1
+ declare function run(): Promise<void>;
2
2
 
3
- export { main as default };
3
+ export { run as default };
package/dist/cli.mjs CHANGED
@@ -1,8 +1,9 @@
1
- #!/usr/bin/env node
2
- import process, { exit, env } from 'node:process';
1
+ import process from 'node:process';
3
2
  import { Command } from '@commander-js/extra-typings';
4
- import updateNotifier from 'update-notifier';
5
- import { L as Log, C as Config, B as Build, S as Serve, T as Test, R as Release } from './shared/zotero-plugin-scaffold.dc0b582a.mjs';
3
+ import { E as ExitSignals, l as logger, C as Config, a as Build, S as Serve, T as Test, R as Release } from './shared/zotero-plugin-scaffold.DoUCzsKc.mjs';
4
+ import { readFile, writeFile } from 'node:fs/promises';
5
+ import { pathExists, ensureFile } from 'fs-extra';
6
+ import tinyUpdateNotifier from 'tiny-update-notifier';
6
7
  import 'c12';
7
8
  import 'es-toolkit';
8
9
  import 'fs-extra/esm';
@@ -10,14 +11,13 @@ import 'hookable';
10
11
  import 'node:readline';
11
12
  import 'chalk';
12
13
  import 'std-env';
13
- import './shared/zotero-plugin-scaffold.77c9802c.mjs';
14
- import 'node:fs/promises';
14
+ import './shared/zotero-plugin-scaffold.v8dJZZ-v.mjs';
15
15
  import 'tinyglobby';
16
+ import 'node:fs';
16
17
  import 'node:path';
17
18
  import 'adm-zip';
18
19
  import 'esbuild';
19
20
  import 'node:crypto';
20
- import 'node:fs';
21
21
  import 'node:child_process';
22
22
  import 'bumpp';
23
23
  import 'chokidar';
@@ -30,15 +30,16 @@ import 'xvfb-ts';
30
30
 
31
31
  const name = "zotero-plugin-scaffold";
32
32
  const type = "module";
33
- const version = "0.2.0-beta.8";
34
- const packageManager = "pnpm@9.15.0";
33
+ const version = "0.2.0";
34
+ const packageManager = "pnpm@9.15.4";
35
35
  const description = "A scaffold for Zotero plugin development.";
36
36
  const author = "northword";
37
37
  const license = "AGPL-3.0-or-later";
38
38
  const homepage = "https://github.com/northword/zotero-plugin-scaffold#readme";
39
39
  const repository = {
40
40
  type: "git",
41
- url: "https://github.com/northword/zotero-plugin-scaffold.git"
41
+ url: "https://github.com/northword/zotero-plugin-scaffold.git",
42
+ directory: "packages/scaffold"
42
43
  };
43
44
  const bugs = {
44
45
  url: "https://github.com/northword/zotero-plugin-scaffold/issues"
@@ -55,6 +56,9 @@ const exports = {
55
56
  types: "./dist/index.d.ts",
56
57
  "import": "./dist/index.mjs"
57
58
  },
59
+ "./cli": {
60
+ "import": "./dist/cli.mjs"
61
+ },
58
62
  "./vendor": {
59
63
  types: "./dist/vendor/index.d.ts",
60
64
  "import": "./dist/vendor/index.mjs"
@@ -64,9 +68,10 @@ const main$1 = "./dist/index.mjs";
64
68
  const module = "./dist/index.mjs";
65
69
  const types = "./dist/index.d.ts";
66
70
  const bin = {
67
- "zotero-plugin": "./dist/cli.mjs"
71
+ "zotero-plugin": "./bin/zotero-plugin.mjs"
68
72
  };
69
73
  const files = [
74
+ "bin",
70
75
  "dist"
71
76
  ];
72
77
  const engines = {
@@ -75,10 +80,6 @@ const engines = {
75
80
  const scripts = {
76
81
  dev: "unbuild --stub",
77
82
  build: "tsc --noEmit && unbuild",
78
- "lint:check": "eslint .",
79
- "lint:fix": "eslint . --fix",
80
- release: "bumpp --commit \"chore(release): publish v%s\"",
81
- "update:deps": "pnpx taze minor -w -f -l",
82
83
  test: "echo \"Error: no test specified\" && exit 1"
83
84
  };
84
85
  const publishConfig = {
@@ -86,8 +87,7 @@ const publishConfig = {
86
87
  registry: "https://registry.npmjs.org"
87
88
  };
88
89
  const directories = {
89
- lib: "dist",
90
- doc: "docs"
90
+ lib: "dist"
91
91
  };
92
92
  const peerDependencies = {
93
93
  "conventional-changelog": "^6.0.0"
@@ -98,41 +98,26 @@ const peerDependenciesMeta = {
98
98
  }
99
99
  };
100
100
  const dependencies = {
101
- "@commander-js/extra-typings": "^12.1.0",
101
+ "@commander-js/extra-typings": "^13.0.0",
102
102
  "adm-zip": "^0.5.16",
103
- bumpp: "^9.9.1",
103
+ bumpp: "^9.10.2",
104
104
  c12: "^2.0.1",
105
- chalk: "^5.3.0",
106
- chokidar: "^4.0.1",
107
- commander: "^12.1.0",
108
- "es-toolkit": "^1.29.0",
109
- esbuild: "^0.24.0",
110
- "fs-extra": "^11.2.0",
105
+ chalk: "^5.4.1",
106
+ chokidar: "^4.0.3",
107
+ commander: "^13.1.0",
108
+ "es-toolkit": "^1.31.0",
109
+ esbuild: "^0.24.2",
110
+ "fs-extra": "^11.3.0",
111
111
  hookable: "^5.5.3",
112
- mime: "^4.0.4",
113
- octokit: "^4.0.2",
112
+ octokit: "^4.1.0",
114
113
  "std-env": "^3.8.0",
114
+ "tiny-update-notifier": "^2.0.0",
115
115
  tinyglobby: "^0.2.10",
116
- "update-notifier": "^7.3.1",
117
116
  "xvfb-ts": "^1.1.0"
118
117
  };
119
118
  const devDependencies = {
120
- "@antfu/eslint-config": "^3.11.2",
121
119
  "@types/adm-zip": "^0.5.7",
122
- "@types/fs-extra": "^11.0.4",
123
- "@types/node": "^22.10.2",
124
- "@types/update-notifier": "^6.0.8",
125
- eslint: "^9.16.0",
126
- "eslint-plugin-format": "^0.1.3",
127
- typescript: "^5.7.2",
128
- unbuild: "^2.0.0"
129
- };
130
- const pnpm = {
131
- peerDependencyRules: {
132
- allowAny: [
133
- "node-fetch"
134
- ]
135
- }
120
+ "@types/fs-extra": "^11.0.4"
136
121
  };
137
122
  const pkg = {
138
123
  name: name,
@@ -159,21 +144,44 @@ const pkg = {
159
144
  peerDependencies: peerDependencies,
160
145
  peerDependenciesMeta: peerDependenciesMeta,
161
146
  dependencies: dependencies,
162
- devDependencies: devDependencies,
163
- pnpm: pnpm
147
+ devDependencies: devDependencies
164
148
  };
165
149
 
166
- const logger = new Log();
150
+ async function checkGitIgnore() {
151
+ if (!pathExists(".git"))
152
+ return;
153
+ await ensureFile(".gitignore");
154
+ const contents = (await readFile(".gitignore", "utf-8")).split("\n");
155
+ const ignores = ["node_modules", ".env", ".scaffold"];
156
+ ignores.forEach((ignore) => {
157
+ if (!contents.includes(ignore))
158
+ contents.push(ignore);
159
+ });
160
+ await writeFile(".gitignore", contents.join("\n"));
161
+ }
162
+
163
+ function updateNotifier(name, version) {
164
+ tinyUpdateNotifier({ pkg: { name, version } }).then((update) => {
165
+ if (update) {
166
+ const notify = () => {
167
+ logger.newLine();
168
+ logger.info(`New version of ${update.name} available!`);
169
+ logger.info(`Update: ${update.current} \u2192 ${update.latest} (${update.type})`);
170
+ logger.newLine();
171
+ };
172
+ ExitSignals.forEach((sig) => process.once(sig, notify));
173
+ }
174
+ }).catch();
175
+ }
176
+
167
177
  async function main() {
168
- var _a;
169
178
  const { name, version } = pkg;
170
- updateNotifier({ pkg: { name, version } }).notify();
171
- process.removeAllListeners("SIGINT");
172
- (_a = env).NODE_ENV ?? (_a.NODE_ENV = "development");
179
+ updateNotifier(name, version);
180
+ process.env.NODE_ENV ??= "development";
173
181
  const cli = new Command();
174
182
  cli.version(version).usage("<command> [options]");
175
183
  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) => {
176
- env.NODE_ENV = options.dev ? "development" : "production";
184
+ process.env.NODE_ENV = options.dev ? "development" : "production";
177
185
  Config.loadConfig({
178
186
  dist: options.dist
179
187
  }).then((ctx) => new Build(ctx).run());
@@ -182,7 +190,7 @@ async function main() {
182
190
  Config.loadConfig({}).then((ctx) => new Serve(ctx).run());
183
191
  });
184
192
  cli.command("test").description("Run tests").option("--abort-on-fail", "Abort the test suite on first failure").option("--exit-on-finish", "Exit the test suite after all tests have run").action((options) => {
185
- env.NODE_ENV = "test";
193
+ process.env.NODE_ENV = "test";
186
194
  Config.loadConfig({}).then((ctx) => {
187
195
  if (options.abortOnFail) {
188
196
  ctx.test.abortOnFail = true;
@@ -197,7 +205,7 @@ async function main() {
197
205
  logger.error("The create not yet implemented");
198
206
  });
199
207
  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) => {
200
- env.NODE_ENV = "production";
208
+ process.env.NODE_ENV = "production";
201
209
  Config.loadConfig({
202
210
  release: {
203
211
  bumpp: {
@@ -214,11 +222,15 @@ async function main() {
214
222
  });
215
223
  cli.parse();
216
224
  }
217
- main().catch(onError);
218
- process.on("uncaughtException", onError);
225
+ async function run() {
226
+ main().then(() => {
227
+ checkGitIgnore();
228
+ }).catch(onError);
229
+ process.on("uncaughtException", onError);
230
+ }
219
231
  function onError(err) {
220
232
  logger.error(err);
221
- exit(1);
233
+ process.exit(1);
222
234
  }
223
235
 
224
- export { main as default };
236
+ export { run as default };