zotero-plugin-scaffold 0.2.0-beta.10 → 0.2.0-beta.12
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 +14 -125
- package/dist/chunks/github.mjs +4 -4
- package/dist/cli.mjs +14 -10
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +1 -1
- package/dist/shared/{zotero-plugin-scaffold.802444a9.mjs → zotero-plugin-scaffold.af8d03c3.mjs} +79 -55
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -14,132 +14,9 @@ This project is under active development, and some APIs may change. However, it
|
|
|
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
|
-
|
|
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
|
-
```
|
|
19
|
+
[Read the Docs to Learn More.](https://northword.github.io/zotero-plugin-scaffold)
|
|
143
20
|
|
|
144
21
|
## Contributing
|
|
145
22
|
|
|
@@ -156,6 +33,18 @@ pnpm install
|
|
|
156
33
|
# and the modified code does not need to be built again.
|
|
157
34
|
pnpm run dev
|
|
158
35
|
|
|
36
|
+
# link local scaffold to your plugin
|
|
37
|
+
cd your-plugin-work-dir/
|
|
38
|
+
pnpm link ../zotero-plugin-scaffold
|
|
39
|
+
cd zotero-plugin-scaffold/
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Now you can make changes to Scaffold and test them in your plugin.
|
|
44
|
+
|
|
45
|
+
When you're done modifying, make sure that you can pass the build and that the code style meets the requirements of this repository.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
159
48
|
# Build
|
|
160
49
|
pnpm run build
|
|
161
50
|
|
package/dist/chunks/github.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { readFile, stat } from 'node:fs/promises';
|
|
2
2
|
import { join, basename } from 'node:path';
|
|
3
|
-
import
|
|
3
|
+
import process from 'node:process';
|
|
4
4
|
import mime from 'mime';
|
|
5
5
|
import { Octokit } from 'octokit';
|
|
6
6
|
import { globSync, glob } from 'tinyglobby';
|
|
7
7
|
import { isCI } from 'std-env';
|
|
8
|
-
import { B as Base } from '../shared/zotero-plugin-scaffold.
|
|
8
|
+
import { B as Base } from '../shared/zotero-plugin-scaffold.af8d03c3.mjs';
|
|
9
9
|
import 'c12';
|
|
10
10
|
import 'es-toolkit';
|
|
11
11
|
import 'fs-extra/esm';
|
|
@@ -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.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import process
|
|
2
|
+
import process from 'node:process';
|
|
3
3
|
import { Command } from '@commander-js/extra-typings';
|
|
4
|
-
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.
|
|
4
|
+
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.af8d03c3.mjs';
|
|
5
5
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
6
6
|
import { pathExists, ensureFile } from 'fs-extra';
|
|
7
7
|
import tinyUpdateNotifier from 'tiny-update-notifier';
|
|
@@ -31,7 +31,7 @@ import 'xvfb-ts';
|
|
|
31
31
|
|
|
32
32
|
const name = "zotero-plugin-scaffold";
|
|
33
33
|
const type = "module";
|
|
34
|
-
const version = "0.2.0-beta.
|
|
34
|
+
const version = "0.2.0-beta.12";
|
|
35
35
|
const packageManager = "pnpm@9.15.0";
|
|
36
36
|
const description = "A scaffold for Zotero plugin development.";
|
|
37
37
|
const author = "northword";
|
|
@@ -80,7 +80,10 @@ const scripts = {
|
|
|
80
80
|
"lint:fix": "eslint . --fix",
|
|
81
81
|
release: "bumpp --commit \"chore(release): publish v%s\"",
|
|
82
82
|
"update:deps": "pnpx taze minor -w -f -l",
|
|
83
|
-
test: "echo \"Error: no test specified\" && exit 1"
|
|
83
|
+
test: "echo \"Error: no test specified\" && exit 1",
|
|
84
|
+
"docs:dev": "vitepress dev docs",
|
|
85
|
+
"docs:build": "vitepress build docs",
|
|
86
|
+
"docs:preview": "vitepress preview docs"
|
|
84
87
|
};
|
|
85
88
|
const publishConfig = {
|
|
86
89
|
access: "public",
|
|
@@ -125,7 +128,8 @@ const devDependencies = {
|
|
|
125
128
|
eslint: "^9.16.0",
|
|
126
129
|
"eslint-plugin-format": "^0.1.3",
|
|
127
130
|
typescript: "^5.7.2",
|
|
128
|
-
unbuild: "^2.0.0"
|
|
131
|
+
unbuild: "^2.0.0",
|
|
132
|
+
vitepress: "^1.5.0"
|
|
129
133
|
};
|
|
130
134
|
const pkg = {
|
|
131
135
|
name: name,
|
|
@@ -186,11 +190,11 @@ async function main() {
|
|
|
186
190
|
var _a;
|
|
187
191
|
const { name, version } = pkg;
|
|
188
192
|
updateNotifier(name, version);
|
|
189
|
-
(_a = env).NODE_ENV ?? (_a.NODE_ENV = "development");
|
|
193
|
+
(_a = process.env).NODE_ENV ?? (_a.NODE_ENV = "development");
|
|
190
194
|
const cli = new Command();
|
|
191
195
|
cli.version(version).usage("<command> [options]");
|
|
192
196
|
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) => {
|
|
193
|
-
env.NODE_ENV = options.dev ? "development" : "production";
|
|
197
|
+
process.env.NODE_ENV = options.dev ? "development" : "production";
|
|
194
198
|
Config.loadConfig({
|
|
195
199
|
dist: options.dist
|
|
196
200
|
}).then((ctx) => new Build(ctx).run());
|
|
@@ -199,7 +203,7 @@ async function main() {
|
|
|
199
203
|
Config.loadConfig({}).then((ctx) => new Serve(ctx).run());
|
|
200
204
|
});
|
|
201
205
|
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) => {
|
|
202
|
-
env.NODE_ENV = "test";
|
|
206
|
+
process.env.NODE_ENV = "test";
|
|
203
207
|
Config.loadConfig({}).then((ctx) => {
|
|
204
208
|
if (options.abortOnFail) {
|
|
205
209
|
ctx.test.abortOnFail = true;
|
|
@@ -214,7 +218,7 @@ async function main() {
|
|
|
214
218
|
logger.error("The create not yet implemented");
|
|
215
219
|
});
|
|
216
220
|
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) => {
|
|
217
|
-
env.NODE_ENV = "production";
|
|
221
|
+
process.env.NODE_ENV = "production";
|
|
218
222
|
Config.loadConfig({
|
|
219
223
|
release: {
|
|
220
224
|
bumpp: {
|
|
@@ -237,7 +241,7 @@ main().then(() => {
|
|
|
237
241
|
process.on("uncaughtException", onError);
|
|
238
242
|
function onError(err) {
|
|
239
243
|
logger.error(err);
|
|
240
|
-
exit(1);
|
|
244
|
+
process.exit(1);
|
|
241
245
|
}
|
|
242
246
|
|
|
243
247
|
export { main as default };
|
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { a as Build, C as Config, R as Release, S as Serve, T as Test, d as defineConfig } from './shared/zotero-plugin-scaffold.
|
|
1
|
+
export { a as Build, C as Config, R as Release, S as Serve, T as Test, d as defineConfig } from './shared/zotero-plugin-scaffold.af8d03c3.mjs';
|
|
2
2
|
import 'c12';
|
|
3
3
|
import 'es-toolkit';
|
|
4
4
|
import 'fs-extra/esm';
|
package/dist/shared/{zotero-plugin-scaffold.802444a9.mjs → zotero-plugin-scaffold.af8d03c3.mjs}
RENAMED
|
@@ -2,7 +2,7 @@ import { loadConfig as loadConfig$1 } from 'c12';
|
|
|
2
2
|
import { isPlainObject, kebabCase, mapValues, toMerged, escapeRegExp, delay, debounce } from 'es-toolkit';
|
|
3
3
|
import { readJsonSync, emptyDir, copy, readJSON, outputJSON, move, writeJson, pathExists, outputFile, remove } from 'fs-extra/esm';
|
|
4
4
|
import { createHooks } from 'hookable';
|
|
5
|
-
import process
|
|
5
|
+
import process from 'node:process';
|
|
6
6
|
import readline from 'node:readline';
|
|
7
7
|
import chalk from 'chalk';
|
|
8
8
|
import { isDebug, isCI, isWindows, isMacOS, isLinux } from 'std-env';
|
|
@@ -43,8 +43,8 @@ const _Log = class _Log {
|
|
|
43
43
|
__publicField$7(this, "logLevel");
|
|
44
44
|
if (isDebug)
|
|
45
45
|
this.logLevel = 0 /* trace */;
|
|
46
|
-
else if (env.ZOTERO_PLUGIN_LOG_LEVEL)
|
|
47
|
-
this.logLevel = LOG_LEVEL[env.ZOTERO_PLUGIN_LOG_LEVEL];
|
|
46
|
+
else if (process.env.ZOTERO_PLUGIN_LOG_LEVEL)
|
|
47
|
+
this.logLevel = LOG_LEVEL[process.env.ZOTERO_PLUGIN_LOG_LEVEL];
|
|
48
48
|
else if (level)
|
|
49
49
|
this.logLevel = level;
|
|
50
50
|
else
|
|
@@ -59,6 +59,9 @@ const _Log = class _Log {
|
|
|
59
59
|
setLogLevel(level) {
|
|
60
60
|
this.logLevel = LOG_LEVEL[level];
|
|
61
61
|
}
|
|
62
|
+
get level() {
|
|
63
|
+
return this.logLevel;
|
|
64
|
+
}
|
|
62
65
|
formatArgs(arg) {
|
|
63
66
|
if (typeof arg === "string")
|
|
64
67
|
return arg;
|
|
@@ -333,7 +336,7 @@ class Build extends Base {
|
|
|
333
336
|
super(ctx);
|
|
334
337
|
__publicField$5(this, "buildTime");
|
|
335
338
|
__publicField$5(this, "isPreRelease");
|
|
336
|
-
(_a = env).NODE_ENV ?? (_a.NODE_ENV = "production");
|
|
339
|
+
(_a = process.env).NODE_ENV ?? (_a.NODE_ENV = "production");
|
|
337
340
|
this.buildTime = "";
|
|
338
341
|
this.isPreRelease = this.ctx.version.includes("-");
|
|
339
342
|
}
|
|
@@ -345,7 +348,7 @@ class Build extends Base {
|
|
|
345
348
|
const t = /* @__PURE__ */ new Date();
|
|
346
349
|
this.buildTime = dateFormat("YYYY-mm-dd HH:MM:SS", t);
|
|
347
350
|
this.logger.info(
|
|
348
|
-
`Building version ${chalk.blue(version)} to ${chalk.blue(dist)} at ${chalk.blue(this.buildTime)} in ${chalk.blue(env.NODE_ENV)} mode.`
|
|
351
|
+
`Building version ${chalk.blue(version)} to ${chalk.blue(dist)} at ${chalk.blue(this.buildTime)} in ${chalk.blue(process.env.NODE_ENV)} mode.`
|
|
349
352
|
);
|
|
350
353
|
await this.ctx.hooks.callHook("build:init", this.ctx);
|
|
351
354
|
await emptyDir(dist);
|
|
@@ -362,7 +365,7 @@ class Build extends Base {
|
|
|
362
365
|
this.logger.tip("Bundling scripts");
|
|
363
366
|
await this.esbuild();
|
|
364
367
|
await this.ctx.hooks.callHook("build:bundle", this.ctx);
|
|
365
|
-
if (env.NODE_ENV === "production") {
|
|
368
|
+
if (process.env.NODE_ENV === "production") {
|
|
366
369
|
this.logger.tip("Packing plugin");
|
|
367
370
|
await this.pack();
|
|
368
371
|
await this.ctx.hooks.callHook("build:pack", this.ctx);
|
|
@@ -733,7 +736,7 @@ ${changelog}
|
|
|
733
736
|
|
|
734
737
|
function isRunning(query) {
|
|
735
738
|
let cmd = "";
|
|
736
|
-
switch (platform) {
|
|
739
|
+
switch (process.platform) {
|
|
737
740
|
case "win32":
|
|
738
741
|
cmd = `tasklist`;
|
|
739
742
|
break;
|
|
@@ -1069,6 +1072,7 @@ class RemoteFirefox {
|
|
|
1069
1072
|
await this.client.connect(port);
|
|
1070
1073
|
return this.client;
|
|
1071
1074
|
} catch (error) {
|
|
1075
|
+
logger.fail("Failed to connecte to RDP client, retry...");
|
|
1072
1076
|
if (isErrorWithCode("ECONNREFUSED", error)) {
|
|
1073
1077
|
await new Promise((resolve) => setTimeout(resolve, RETRY_INTERVAL));
|
|
1074
1078
|
lastError = error;
|
|
@@ -1275,18 +1279,17 @@ class ZoteroRunner {
|
|
|
1275
1279
|
}
|
|
1276
1280
|
const remotePort = await findFreeTcpPort();
|
|
1277
1281
|
args.push("-start-debugger-server", String(remotePort));
|
|
1278
|
-
|
|
1282
|
+
logger.debug("Zotero start args: ", args);
|
|
1283
|
+
const env = {
|
|
1284
|
+
...process.env,
|
|
1279
1285
|
XPCOM_DEBUG_BREAK: "stack",
|
|
1280
1286
|
NS_TRACE_MALLOC_DISABLE_STACKS: "1"
|
|
1281
1287
|
};
|
|
1282
|
-
this.zotero = spawn(this.options.binaryPath, args, {
|
|
1283
|
-
|
|
1284
|
-
...env,
|
|
1285
|
-
...defaultFirefoxEnv
|
|
1286
|
-
}
|
|
1287
|
-
});
|
|
1288
|
+
this.zotero = spawn(this.options.binaryPath, args, { env });
|
|
1289
|
+
logger.debug("Zotero started, pid:", this.zotero.pid);
|
|
1288
1290
|
this.zotero.stdout?.on("data", (_data) => {
|
|
1289
1291
|
});
|
|
1292
|
+
logger.debug("Connecting to the remote Firefox debugger...");
|
|
1290
1293
|
await this.remoteFirefox.connect(remotePort);
|
|
1291
1294
|
logger.debug(`Connected to the remote Firefox debugger on port: ${remotePort}`);
|
|
1292
1295
|
}
|
|
@@ -1412,8 +1415,8 @@ class ZoteroRunner {
|
|
|
1412
1415
|
function killZotero() {
|
|
1413
1416
|
function kill() {
|
|
1414
1417
|
try {
|
|
1415
|
-
if (env.ZOTERO_PLUGIN_KILL_COMMAND) {
|
|
1416
|
-
execSync(env.ZOTERO_PLUGIN_KILL_COMMAND);
|
|
1418
|
+
if (process.env.ZOTERO_PLUGIN_KILL_COMMAND) {
|
|
1419
|
+
execSync(process.env.ZOTERO_PLUGIN_KILL_COMMAND);
|
|
1417
1420
|
} else if (isWindows) {
|
|
1418
1421
|
execSync("taskkill /f /im zotero.exe");
|
|
1419
1422
|
} else if (isMacOS) {
|
|
@@ -1457,7 +1460,7 @@ class Serve extends Base {
|
|
|
1457
1460
|
});
|
|
1458
1461
|
__publicField$1(this, "onZoteroExit", (_code, _signal) => {
|
|
1459
1462
|
this.logger.info(`Zotero terminated.`);
|
|
1460
|
-
exit();
|
|
1463
|
+
process.exit();
|
|
1461
1464
|
});
|
|
1462
1465
|
(_a = process.env).NODE_ENV ?? (_a.NODE_ENV = "development");
|
|
1463
1466
|
this.builder = new Build(ctx);
|
|
@@ -1528,7 +1531,7 @@ class Serve extends Base {
|
|
|
1528
1531
|
get zoteroBinPath() {
|
|
1529
1532
|
if (this._zoteroBinPath)
|
|
1530
1533
|
return this._zoteroBinPath;
|
|
1531
|
-
this._zoteroBinPath = env.ZOTERO_PLUGIN_ZOTERO_BIN_PATH;
|
|
1534
|
+
this._zoteroBinPath = process.env.ZOTERO_PLUGIN_ZOTERO_BIN_PATH;
|
|
1532
1535
|
if (!this._zoteroBinPath || !existsSync(this._zoteroBinPath))
|
|
1533
1536
|
throw new Error("The Zotero binary not found.");
|
|
1534
1537
|
return this._zoteroBinPath;
|
|
@@ -1536,13 +1539,13 @@ class Serve extends Base {
|
|
|
1536
1539
|
get profilePath() {
|
|
1537
1540
|
if (this._profilePath)
|
|
1538
1541
|
return this._profilePath;
|
|
1539
|
-
this._profilePath = env.ZOTERO_PLUGIN_PROFILE_PATH;
|
|
1542
|
+
this._profilePath = process.env.ZOTERO_PLUGIN_PROFILE_PATH;
|
|
1540
1543
|
if (!this._profilePath || !existsSync(this._profilePath))
|
|
1541
1544
|
throw new Error("The Zotero profile not found.");
|
|
1542
1545
|
return this._profilePath;
|
|
1543
1546
|
}
|
|
1544
1547
|
get dataDir() {
|
|
1545
|
-
return env.ZOTERO_PLUGIN_DATA_DIR ?? "";
|
|
1548
|
+
return process.env.ZOTERO_PLUGIN_DATA_DIR ?? "";
|
|
1546
1549
|
}
|
|
1547
1550
|
}
|
|
1548
1551
|
|
|
@@ -1551,42 +1554,63 @@ async function saveResource(url, path) {
|
|
|
1551
1554
|
await outputFile(path, await res.text());
|
|
1552
1555
|
}
|
|
1553
1556
|
|
|
1557
|
+
function isPackageInstalled(packageName) {
|
|
1558
|
+
try {
|
|
1559
|
+
execSync(`dpkg-query -W ${packageName}`, { stdio: "ignore" });
|
|
1560
|
+
return true;
|
|
1561
|
+
} catch {
|
|
1562
|
+
return false;
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
function installPackage(packageName) {
|
|
1566
|
+
const debug = isDebug || logger.level <= LOG_LEVEL.debug;
|
|
1567
|
+
try {
|
|
1568
|
+
logger.debug(`Installing ${packageName}...`);
|
|
1569
|
+
execSync(`sudo apt update && sudo apt install -y ${packageName}`, { stdio: debug ? "inherit" : "pipe" });
|
|
1570
|
+
logger.debug(`${packageName} installed successfully.`);
|
|
1571
|
+
} catch (error) {
|
|
1572
|
+
logger.fail(`Failed to install ${packageName}.`, error);
|
|
1573
|
+
throw error;
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
function checkAndInstallDependencies(packages) {
|
|
1577
|
+
packages.forEach((pkg) => {
|
|
1578
|
+
if (isPackageInstalled(pkg)) {
|
|
1579
|
+
logger.debug(`${pkg} is already installed.`);
|
|
1580
|
+
} else {
|
|
1581
|
+
installPackage(pkg);
|
|
1582
|
+
}
|
|
1583
|
+
});
|
|
1584
|
+
}
|
|
1554
1585
|
async function installXvfb() {
|
|
1555
|
-
logger.debug("Installing xvfb...");
|
|
1556
1586
|
if (!isLinux) {
|
|
1557
1587
|
logger.error("Unsupported platform. Please install Xvfb manually.");
|
|
1558
|
-
|
|
1588
|
+
return;
|
|
1559
1589
|
}
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
throw new Error("Unsupported Linux distribution.");
|
|
1573
|
-
}
|
|
1574
|
-
logger.debug("Xvfb installation completed.");
|
|
1575
|
-
} catch (error) {
|
|
1576
|
-
logger.error("Failed to install Xvfb:", error);
|
|
1577
|
-
exit(1);
|
|
1578
|
-
}
|
|
1590
|
+
const osId = execSync("cat /etc/os-release | grep '^ID='").toString();
|
|
1591
|
+
if (!(osId.includes("ubuntu") || osId.includes("debian"))) {
|
|
1592
|
+
logger.error("Unsupported Linux distribution.");
|
|
1593
|
+
return;
|
|
1594
|
+
}
|
|
1595
|
+
checkAndInstallDependencies(["xvfb", "x11-xkb-utils", "xkb-data"]);
|
|
1596
|
+
}
|
|
1597
|
+
async function installDepsForUbuntu24() {
|
|
1598
|
+
const version = execSync("cat /etc/os-release | grep '^VERSION_ID='").toString();
|
|
1599
|
+
if (!version.includes("24")) {
|
|
1600
|
+
logger.error("Skip to install deps due to version not 24.04.");
|
|
1601
|
+
return;
|
|
1579
1602
|
}
|
|
1603
|
+
checkAndInstallDependencies(["libasound2t64", "libdbus-glib-1-2"]);
|
|
1580
1604
|
}
|
|
1581
1605
|
async function installZoteroLinux() {
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
execSync("tar -xvf zotero.tar.bz2", { stdio: "pipe" });
|
|
1586
|
-
} catch (e) {
|
|
1587
|
-
logger.error(e);
|
|
1588
|
-
throw new Error("Zotero extracted failed");
|
|
1606
|
+
if (process.env.ZOTERO_PLUGIN_ZOTERO_BIN_PATH) {
|
|
1607
|
+
logger.debug("Local Zotero found, skip to download.");
|
|
1608
|
+
return;
|
|
1589
1609
|
}
|
|
1610
|
+
logger.debug("Installing Zotero...");
|
|
1611
|
+
execSync("wget -O zotero.tar.bz2 'https://www.zotero.org/download/client/dl?platform=linux-x86_64&channel=beta'", { stdio: "pipe" });
|
|
1612
|
+
execSync("tar -xvf zotero.tar.bz2", { stdio: "pipe" });
|
|
1613
|
+
process.env.ZOTERO_PLUGIN_ZOTERO_BIN_PATH = `${process.cwd()}/Zotero_linux-x86_64/zotero`;
|
|
1590
1614
|
}
|
|
1591
1615
|
|
|
1592
1616
|
var __defProp = Object.defineProperty;
|
|
@@ -1608,16 +1632,16 @@ class Test extends Base {
|
|
|
1608
1632
|
this.ctx.hooks.callHook("test:exit", this.ctx);
|
|
1609
1633
|
if (code === 1) {
|
|
1610
1634
|
this.logger.error("Test run failed");
|
|
1611
|
-
exit(1);
|
|
1635
|
+
process.exit(1);
|
|
1612
1636
|
} else if (code === "SIGINT") {
|
|
1613
1637
|
this.logger.info("Tester shutdown by user request");
|
|
1614
|
-
exit();
|
|
1638
|
+
process.exit();
|
|
1615
1639
|
} else {
|
|
1616
1640
|
this.logger.success("Test run completed successfully");
|
|
1617
|
-
exit();
|
|
1641
|
+
process.exit();
|
|
1618
1642
|
}
|
|
1619
1643
|
});
|
|
1620
|
-
(_a = env).NODE_ENV ?? (_a.NODE_ENV = "test");
|
|
1644
|
+
(_a = process.env).NODE_ENV ?? (_a.NODE_ENV = "test");
|
|
1621
1645
|
this.builder = new Build(ctx);
|
|
1622
1646
|
if (isCI) {
|
|
1623
1647
|
this.ctx.test.exitOnFinish = true;
|
|
@@ -2071,8 +2095,8 @@ class Test extends Base {
|
|
|
2071
2095
|
}
|
|
2072
2096
|
async startZoteroHeadless() {
|
|
2073
2097
|
await installXvfb();
|
|
2098
|
+
await installDepsForUbuntu24();
|
|
2074
2099
|
await installZoteroLinux();
|
|
2075
|
-
env.ZOTERO_PLUGIN_ZOTERO_BIN_PATH = `${cwd()}/Zotero_linux-x86_64/zotero`;
|
|
2076
2100
|
const xvfb = new Xvfb({
|
|
2077
2101
|
timeout: 2e3
|
|
2078
2102
|
});
|
|
@@ -2098,9 +2122,9 @@ class Test extends Base {
|
|
|
2098
2122
|
await this.runner.run();
|
|
2099
2123
|
}
|
|
2100
2124
|
get zoteroBinPath() {
|
|
2101
|
-
if (!env.ZOTERO_PLUGIN_ZOTERO_BIN_PATH)
|
|
2125
|
+
if (!process.env.ZOTERO_PLUGIN_ZOTERO_BIN_PATH)
|
|
2102
2126
|
throw new Error("No Zotero Found.");
|
|
2103
|
-
return env.ZOTERO_PLUGIN_ZOTERO_BIN_PATH;
|
|
2127
|
+
return process.env.ZOTERO_PLUGIN_ZOTERO_BIN_PATH;
|
|
2104
2128
|
}
|
|
2105
2129
|
get profilePath() {
|
|
2106
2130
|
return `.scaffold/test/profile`;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zotero-plugin-scaffold",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.0-beta.
|
|
4
|
+
"version": "0.2.0-beta.12",
|
|
5
5
|
"description": "A scaffold for Zotero plugin development.",
|
|
6
6
|
"author": "northword",
|
|
7
7
|
"license": "AGPL-3.0-or-later",
|
|
@@ -85,7 +85,8 @@
|
|
|
85
85
|
"eslint": "^9.16.0",
|
|
86
86
|
"eslint-plugin-format": "^0.1.3",
|
|
87
87
|
"typescript": "^5.7.2",
|
|
88
|
-
"unbuild": "^2.0.0"
|
|
88
|
+
"unbuild": "^2.0.0",
|
|
89
|
+
"vitepress": "^1.5.0"
|
|
89
90
|
},
|
|
90
91
|
"scripts": {
|
|
91
92
|
"dev": "unbuild --stub",
|
|
@@ -94,6 +95,9 @@
|
|
|
94
95
|
"lint:fix": "eslint . --fix",
|
|
95
96
|
"release": "bumpp --commit \"chore(release): publish v%s\"",
|
|
96
97
|
"update:deps": "pnpx taze minor -w -f -l",
|
|
97
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
98
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
99
|
+
"docs:dev": "vitepress dev docs",
|
|
100
|
+
"docs:build": "vitepress build docs",
|
|
101
|
+
"docs:preview": "vitepress preview docs"
|
|
98
102
|
}
|
|
99
103
|
}
|