zotero-plugin-scaffold 0.2.0-beta.13 → 0.2.0-beta.15
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/dist/chunks/github.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import process from 'node:process';
|
|
|
4
4
|
import { Octokit } from 'octokit';
|
|
5
5
|
import { globSync, glob } from 'tinyglobby';
|
|
6
6
|
import { isCI } from 'std-env';
|
|
7
|
-
import { B as Base } from '../shared/zotero-plugin-scaffold.
|
|
7
|
+
import { B as Base } from '../shared/zotero-plugin-scaffold.DQuI5OK-.mjs';
|
|
8
8
|
import 'c12';
|
|
9
9
|
import 'es-toolkit';
|
|
10
10
|
import 'fs-extra/esm';
|
|
@@ -12,10 +12,10 @@ import 'hookable';
|
|
|
12
12
|
import 'node:readline';
|
|
13
13
|
import 'chalk';
|
|
14
14
|
import '../shared/zotero-plugin-scaffold.v8dJZZ-v.mjs';
|
|
15
|
+
import 'node:fs';
|
|
15
16
|
import 'adm-zip';
|
|
16
17
|
import 'esbuild';
|
|
17
18
|
import 'node:crypto';
|
|
18
|
-
import 'node:fs';
|
|
19
19
|
import 'node:child_process';
|
|
20
20
|
import 'bumpp';
|
|
21
21
|
import 'chokidar';
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
2
|
import { Command } from '@commander-js/extra-typings';
|
|
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.
|
|
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.DQuI5OK-.mjs';
|
|
4
4
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
5
5
|
import { pathExists, ensureFile } from 'fs-extra';
|
|
6
6
|
import tinyUpdateNotifier from 'tiny-update-notifier';
|
|
@@ -13,11 +13,11 @@ import 'chalk';
|
|
|
13
13
|
import 'std-env';
|
|
14
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,8 +30,8 @@ import 'xvfb-ts';
|
|
|
30
30
|
|
|
31
31
|
const name = "zotero-plugin-scaffold";
|
|
32
32
|
const type = "module";
|
|
33
|
-
const version = "0.2.0-beta.
|
|
34
|
-
const packageManager = "pnpm@9.15.
|
|
33
|
+
const version = "0.2.0-beta.15";
|
|
34
|
+
const packageManager = "pnpm@9.15.2";
|
|
35
35
|
const description = "A scaffold for Zotero plugin development.";
|
|
36
36
|
const author = "northword";
|
|
37
37
|
const license = "AGPL-3.0-or-later";
|
|
@@ -98,13 +98,13 @@ const peerDependenciesMeta = {
|
|
|
98
98
|
}
|
|
99
99
|
};
|
|
100
100
|
const dependencies = {
|
|
101
|
-
"@commander-js/extra-typings": "^
|
|
101
|
+
"@commander-js/extra-typings": "^13.0.0",
|
|
102
102
|
"adm-zip": "^0.5.16",
|
|
103
103
|
bumpp: "^9.9.2",
|
|
104
104
|
c12: "^2.0.1",
|
|
105
105
|
chalk: "^5.4.1",
|
|
106
106
|
chokidar: "^4.0.3",
|
|
107
|
-
commander: "^
|
|
107
|
+
commander: "^13.0.0",
|
|
108
108
|
"es-toolkit": "^1.31.0",
|
|
109
109
|
esbuild: "^0.24.2",
|
|
110
110
|
"fs-extra": "^11.2.0",
|
package/dist/index.d.mts
CHANGED
|
@@ -51,14 +51,9 @@ interface Manifest {
|
|
|
51
51
|
zotero: {
|
|
52
52
|
id: string;
|
|
53
53
|
update_url: string;
|
|
54
|
-
strict_min_version
|
|
54
|
+
strict_min_version?: string;
|
|
55
55
|
strict_max_version?: string;
|
|
56
56
|
};
|
|
57
|
-
gecko: {
|
|
58
|
-
id: string;
|
|
59
|
-
update_url: string;
|
|
60
|
-
strict_min_version: string;
|
|
61
|
-
};
|
|
62
57
|
};
|
|
63
58
|
}
|
|
64
59
|
|
|
@@ -81,7 +76,7 @@ interface UpdateJSON {
|
|
|
81
76
|
update_hash?: string;
|
|
82
77
|
applications: {
|
|
83
78
|
zotero: {
|
|
84
|
-
strict_min_version
|
|
79
|
+
strict_min_version?: string;
|
|
85
80
|
strict_max_version?: string;
|
|
86
81
|
};
|
|
87
82
|
[application: string]: {
|
|
@@ -301,6 +296,40 @@ interface BuildConfig {
|
|
|
301
296
|
*/
|
|
302
297
|
prefixFluentMessages: boolean;
|
|
303
298
|
};
|
|
299
|
+
prefs: {
|
|
300
|
+
/**
|
|
301
|
+
* Prefixes the keys of preferences in `prefs.js` and
|
|
302
|
+
* the value of the `preference` attribute in XHTML files.
|
|
303
|
+
*
|
|
304
|
+
* 为 `prefs.js` 中的首选项键和 XHTML 文件中的 `preference` 属性的值
|
|
305
|
+
* 添加前缀。
|
|
306
|
+
*
|
|
307
|
+
* @default true
|
|
308
|
+
*/
|
|
309
|
+
prefixPrefKeys: boolean;
|
|
310
|
+
/**
|
|
311
|
+
* Prefixes for Preference Keys, no dot at the end.
|
|
312
|
+
*
|
|
313
|
+
* 首选项键的前缀,结尾不需要加点号。
|
|
314
|
+
*
|
|
315
|
+
* @default 'extensions.${namespace}'
|
|
316
|
+
*/
|
|
317
|
+
prefix: string;
|
|
318
|
+
/**
|
|
319
|
+
* Generate prefs.d.ts form prefs.js.
|
|
320
|
+
*
|
|
321
|
+
* - false: disable
|
|
322
|
+
* - string: path of dts file
|
|
323
|
+
*
|
|
324
|
+
* 为首选项生成类型声明文件。
|
|
325
|
+
*
|
|
326
|
+
* - false: 禁用
|
|
327
|
+
* - string:dts 文件路径
|
|
328
|
+
*
|
|
329
|
+
* @default 'typings/prefs.d.ts'
|
|
330
|
+
*/
|
|
331
|
+
dts: false | string;
|
|
332
|
+
};
|
|
304
333
|
/**
|
|
305
334
|
* Configurations of esbuild.
|
|
306
335
|
*
|
|
@@ -426,6 +455,8 @@ interface ServerConfig {
|
|
|
426
455
|
* @default false
|
|
427
456
|
*/
|
|
428
457
|
asProxy: boolean;
|
|
458
|
+
prebuild: boolean;
|
|
459
|
+
createProfileIfMissing: boolean;
|
|
429
460
|
/**
|
|
430
461
|
* The lifecycle hook.
|
|
431
462
|
*/
|
|
@@ -726,6 +757,7 @@ interface Hooks extends BuildHooks, ServeHooks, ReleaseHooks, TestHooks {
|
|
|
726
757
|
type RecursivePartial<T> = {
|
|
727
758
|
[P in keyof T]?: T[P] extends object ? RecursivePartial<T[P]> : T[P];
|
|
728
759
|
};
|
|
760
|
+
|
|
729
761
|
/**
|
|
730
762
|
* User config
|
|
731
763
|
*/
|
|
@@ -789,6 +821,7 @@ declare class Build extends Base {
|
|
|
789
821
|
*/
|
|
790
822
|
makeManifest(): Promise<void>;
|
|
791
823
|
prepareLocaleFiles(): Promise<void>;
|
|
824
|
+
preparePrefs(): Promise<void>;
|
|
792
825
|
esbuild(): Promise<esbuild.BuildResult<esbuild.BuildOptions>[]> | undefined;
|
|
793
826
|
makeUpdateJson(): Promise<void>;
|
|
794
827
|
pack(): Promise<void>;
|
|
@@ -816,7 +849,6 @@ declare class Serve extends Base {
|
|
|
816
849
|
private builder;
|
|
817
850
|
private runner?;
|
|
818
851
|
private _zoteroBinPath?;
|
|
819
|
-
private _profilePath?;
|
|
820
852
|
constructor(ctx: Context);
|
|
821
853
|
run(): Promise<void>;
|
|
822
854
|
/**
|
|
@@ -828,8 +860,8 @@ declare class Serve extends Base {
|
|
|
828
860
|
exit: () => never;
|
|
829
861
|
private onZoteroExit;
|
|
830
862
|
get zoteroBinPath(): string;
|
|
831
|
-
get profilePath(): string;
|
|
832
|
-
get dataDir(): string;
|
|
863
|
+
get profilePath(): string | undefined;
|
|
864
|
+
get dataDir(): string | undefined;
|
|
833
865
|
}
|
|
834
866
|
|
|
835
867
|
declare class Test extends Base {
|
package/dist/index.d.ts
CHANGED
|
@@ -51,14 +51,9 @@ interface Manifest {
|
|
|
51
51
|
zotero: {
|
|
52
52
|
id: string;
|
|
53
53
|
update_url: string;
|
|
54
|
-
strict_min_version
|
|
54
|
+
strict_min_version?: string;
|
|
55
55
|
strict_max_version?: string;
|
|
56
56
|
};
|
|
57
|
-
gecko: {
|
|
58
|
-
id: string;
|
|
59
|
-
update_url: string;
|
|
60
|
-
strict_min_version: string;
|
|
61
|
-
};
|
|
62
57
|
};
|
|
63
58
|
}
|
|
64
59
|
|
|
@@ -81,7 +76,7 @@ interface UpdateJSON {
|
|
|
81
76
|
update_hash?: string;
|
|
82
77
|
applications: {
|
|
83
78
|
zotero: {
|
|
84
|
-
strict_min_version
|
|
79
|
+
strict_min_version?: string;
|
|
85
80
|
strict_max_version?: string;
|
|
86
81
|
};
|
|
87
82
|
[application: string]: {
|
|
@@ -301,6 +296,40 @@ interface BuildConfig {
|
|
|
301
296
|
*/
|
|
302
297
|
prefixFluentMessages: boolean;
|
|
303
298
|
};
|
|
299
|
+
prefs: {
|
|
300
|
+
/**
|
|
301
|
+
* Prefixes the keys of preferences in `prefs.js` and
|
|
302
|
+
* the value of the `preference` attribute in XHTML files.
|
|
303
|
+
*
|
|
304
|
+
* 为 `prefs.js` 中的首选项键和 XHTML 文件中的 `preference` 属性的值
|
|
305
|
+
* 添加前缀。
|
|
306
|
+
*
|
|
307
|
+
* @default true
|
|
308
|
+
*/
|
|
309
|
+
prefixPrefKeys: boolean;
|
|
310
|
+
/**
|
|
311
|
+
* Prefixes for Preference Keys, no dot at the end.
|
|
312
|
+
*
|
|
313
|
+
* 首选项键的前缀,结尾不需要加点号。
|
|
314
|
+
*
|
|
315
|
+
* @default 'extensions.${namespace}'
|
|
316
|
+
*/
|
|
317
|
+
prefix: string;
|
|
318
|
+
/**
|
|
319
|
+
* Generate prefs.d.ts form prefs.js.
|
|
320
|
+
*
|
|
321
|
+
* - false: disable
|
|
322
|
+
* - string: path of dts file
|
|
323
|
+
*
|
|
324
|
+
* 为首选项生成类型声明文件。
|
|
325
|
+
*
|
|
326
|
+
* - false: 禁用
|
|
327
|
+
* - string:dts 文件路径
|
|
328
|
+
*
|
|
329
|
+
* @default 'typings/prefs.d.ts'
|
|
330
|
+
*/
|
|
331
|
+
dts: false | string;
|
|
332
|
+
};
|
|
304
333
|
/**
|
|
305
334
|
* Configurations of esbuild.
|
|
306
335
|
*
|
|
@@ -426,6 +455,8 @@ interface ServerConfig {
|
|
|
426
455
|
* @default false
|
|
427
456
|
*/
|
|
428
457
|
asProxy: boolean;
|
|
458
|
+
prebuild: boolean;
|
|
459
|
+
createProfileIfMissing: boolean;
|
|
429
460
|
/**
|
|
430
461
|
* The lifecycle hook.
|
|
431
462
|
*/
|
|
@@ -726,6 +757,7 @@ interface Hooks extends BuildHooks, ServeHooks, ReleaseHooks, TestHooks {
|
|
|
726
757
|
type RecursivePartial<T> = {
|
|
727
758
|
[P in keyof T]?: T[P] extends object ? RecursivePartial<T[P]> : T[P];
|
|
728
759
|
};
|
|
760
|
+
|
|
729
761
|
/**
|
|
730
762
|
* User config
|
|
731
763
|
*/
|
|
@@ -789,6 +821,7 @@ declare class Build extends Base {
|
|
|
789
821
|
*/
|
|
790
822
|
makeManifest(): Promise<void>;
|
|
791
823
|
prepareLocaleFiles(): Promise<void>;
|
|
824
|
+
preparePrefs(): Promise<void>;
|
|
792
825
|
esbuild(): Promise<esbuild.BuildResult<esbuild.BuildOptions>[]> | undefined;
|
|
793
826
|
makeUpdateJson(): Promise<void>;
|
|
794
827
|
pack(): Promise<void>;
|
|
@@ -816,7 +849,6 @@ declare class Serve extends Base {
|
|
|
816
849
|
private builder;
|
|
817
850
|
private runner?;
|
|
818
851
|
private _zoteroBinPath?;
|
|
819
|
-
private _profilePath?;
|
|
820
852
|
constructor(ctx: Context);
|
|
821
853
|
run(): Promise<void>;
|
|
822
854
|
/**
|
|
@@ -828,8 +860,8 @@ declare class Serve extends Base {
|
|
|
828
860
|
exit: () => never;
|
|
829
861
|
private onZoteroExit;
|
|
830
862
|
get zoteroBinPath(): string;
|
|
831
|
-
get profilePath(): string;
|
|
832
|
-
get dataDir(): string;
|
|
863
|
+
get profilePath(): string | undefined;
|
|
864
|
+
get dataDir(): string | undefined;
|
|
833
865
|
}
|
|
834
866
|
|
|
835
867
|
declare class Test extends Base {
|
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.DQuI5OK-.mjs';
|
|
2
2
|
import 'c12';
|
|
3
3
|
import 'es-toolkit';
|
|
4
4
|
import 'fs-extra/esm';
|
|
@@ -10,11 +10,11 @@ import 'std-env';
|
|
|
10
10
|
import './shared/zotero-plugin-scaffold.v8dJZZ-v.mjs';
|
|
11
11
|
import 'node:fs/promises';
|
|
12
12
|
import 'tinyglobby';
|
|
13
|
+
import 'node:fs';
|
|
13
14
|
import 'node:path';
|
|
14
15
|
import 'adm-zip';
|
|
15
16
|
import 'esbuild';
|
|
16
17
|
import 'node:crypto';
|
|
17
|
-
import 'node:fs';
|
|
18
18
|
import 'node:child_process';
|
|
19
19
|
import 'bumpp';
|
|
20
20
|
import 'chokidar';
|
package/dist/shared/{zotero-plugin-scaffold.CnLqPvW1.mjs → zotero-plugin-scaffold.DQuI5OK-.mjs}
RENAMED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { loadConfig as loadConfig$1 } from 'c12';
|
|
2
|
-
import { isPlainObject, kebabCase, mapValues, toMerged, escapeRegExp, delay, debounce } from 'es-toolkit';
|
|
3
|
-
import { readJsonSync, emptyDir, copy, readJSON, outputJSON, move, writeJson, pathExists,
|
|
2
|
+
import { isPlainObject, kebabCase, mapValues, isNotNil, toMerged, escapeRegExp, delay, debounce } from 'es-toolkit';
|
|
3
|
+
import { readJsonSync, outputFile, emptyDir, copy, readJSON, outputJSON, move, writeJson, pathExists, ensureDir, remove } from 'fs-extra/esm';
|
|
4
4
|
import { createHooks } from 'hookable';
|
|
5
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';
|
|
9
9
|
import { p as parseRepoUrl, d as dateFormat, t as template, b as toArray, a as replaceInFile } from './zotero-plugin-scaffold.v8dJZZ-v.mjs';
|
|
10
|
+
import { createReadStream, existsSync } from 'node:fs';
|
|
10
11
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
11
12
|
import { basename, dirname, join, resolve } from 'node:path';
|
|
12
13
|
import AdmZip from 'adm-zip';
|
|
13
14
|
import { build } from 'esbuild';
|
|
14
15
|
import { glob } from 'tinyglobby';
|
|
15
16
|
import { createHash } from 'node:crypto';
|
|
16
|
-
import { createReadStream, existsSync } from 'node:fs';
|
|
17
17
|
import { execSync, spawn } from 'node:child_process';
|
|
18
18
|
import { versionBump, ProgressEvent } from 'bumpp';
|
|
19
19
|
import chokidar from 'chokidar';
|
|
@@ -146,6 +146,7 @@ function resolveConfig(config) {
|
|
|
146
146
|
config.id ||= config.name;
|
|
147
147
|
config.namespace ||= config.name;
|
|
148
148
|
config.xpiName ||= kebabCase(config.name);
|
|
149
|
+
config.build.prefs.prefix ||= `extensions.${config.namespace}`;
|
|
149
150
|
const isPreRelease = version.includes("-");
|
|
150
151
|
const templateData = {
|
|
151
152
|
owner,
|
|
@@ -192,31 +193,22 @@ const defaultConfig = {
|
|
|
192
193
|
prefixFluentMessages: true,
|
|
193
194
|
prefixLocaleFiles: true
|
|
194
195
|
},
|
|
196
|
+
prefs: {
|
|
197
|
+
prefix: "",
|
|
198
|
+
prefixPrefKeys: true,
|
|
199
|
+
dts: "typings/prefs.d.ts"
|
|
200
|
+
},
|
|
195
201
|
esbuildOptions: [],
|
|
196
202
|
makeManifest: {
|
|
197
203
|
enable: true,
|
|
198
204
|
template: {
|
|
199
205
|
manifest_version: 2,
|
|
200
|
-
name: "
|
|
201
|
-
version: "
|
|
202
|
-
description: "__description__",
|
|
203
|
-
homepage_url: "__homepage__",
|
|
204
|
-
author: "__author__",
|
|
205
|
-
icons: {
|
|
206
|
-
48: "content/icons/favicon@0.5x.png",
|
|
207
|
-
96: "content/icons/favicon.png"
|
|
208
|
-
},
|
|
206
|
+
name: "",
|
|
207
|
+
version: "",
|
|
209
208
|
applications: {
|
|
210
209
|
zotero: {
|
|
211
|
-
id: "
|
|
212
|
-
update_url: "
|
|
213
|
-
strict_min_version: "6.999",
|
|
214
|
-
strict_max_version: "7.0.*"
|
|
215
|
-
},
|
|
216
|
-
gecko: {
|
|
217
|
-
id: "__addonID__",
|
|
218
|
-
update_url: "__updateURL__",
|
|
219
|
-
strict_min_version: "102"
|
|
210
|
+
id: "",
|
|
211
|
+
update_url: ""
|
|
220
212
|
}
|
|
221
213
|
}
|
|
222
214
|
}
|
|
@@ -231,6 +223,9 @@ const defaultConfig = {
|
|
|
231
223
|
devtools: true,
|
|
232
224
|
startArgs: [],
|
|
233
225
|
asProxy: false,
|
|
226
|
+
prebuild: true,
|
|
227
|
+
// keepProfileChanges: true,
|
|
228
|
+
createProfileIfMissing: true,
|
|
234
229
|
hooks: {}
|
|
235
230
|
},
|
|
236
231
|
addonLint: {},
|
|
@@ -301,6 +296,109 @@ function generateHash(filePath, algorithm) {
|
|
|
301
296
|
});
|
|
302
297
|
}
|
|
303
298
|
|
|
299
|
+
class PrefsManager {
|
|
300
|
+
namespace;
|
|
301
|
+
prefs = {};
|
|
302
|
+
constructor(namespace) {
|
|
303
|
+
this.namespace = namespace;
|
|
304
|
+
}
|
|
305
|
+
parse(content) {
|
|
306
|
+
const prefPattern = /^(pref|user_pref)\s*\(\s*["']([^"']+)["']\s*,\s*(.+)\s*\)\s*;$/gm;
|
|
307
|
+
const matches = content.matchAll(prefPattern);
|
|
308
|
+
for (const match of matches) {
|
|
309
|
+
const key = match[2].trim();
|
|
310
|
+
const value = match[3].trim();
|
|
311
|
+
this.prefs[key] = value;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
render() {
|
|
315
|
+
return Object.entries(this.prefs).map(([key, value]) => {
|
|
316
|
+
if (!isNotNil(value))
|
|
317
|
+
return "";
|
|
318
|
+
let cleanValue = "";
|
|
319
|
+
if (typeof value === "boolean") {
|
|
320
|
+
cleanValue = `${value}`;
|
|
321
|
+
} else if (typeof value === "string") {
|
|
322
|
+
cleanValue = value;
|
|
323
|
+
} else if (typeof value === "number") {
|
|
324
|
+
cleanValue = value.toString();
|
|
325
|
+
}
|
|
326
|
+
return `${this.namespace}("${key}", ${cleanValue});`;
|
|
327
|
+
}).filter((c) => !!c).join("\n");
|
|
328
|
+
}
|
|
329
|
+
async read(path) {
|
|
330
|
+
const content = await readFile(path, "utf-8");
|
|
331
|
+
this.parse(content);
|
|
332
|
+
}
|
|
333
|
+
async write(path) {
|
|
334
|
+
const content = this.render();
|
|
335
|
+
await outputFile(path, content, "utf-8");
|
|
336
|
+
logger.debug("The <profile>/prefs.js has been modified.");
|
|
337
|
+
}
|
|
338
|
+
setPref(key, value) {
|
|
339
|
+
this.prefs[key] = value;
|
|
340
|
+
}
|
|
341
|
+
setPrefs(prefs) {
|
|
342
|
+
Object.entries(prefs).forEach(([key, value]) => {
|
|
343
|
+
this.setPref(key, value);
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
getPref(key) {
|
|
347
|
+
return this.prefs[key] ?? void 0;
|
|
348
|
+
}
|
|
349
|
+
getPrefs() {
|
|
350
|
+
return this.prefs;
|
|
351
|
+
}
|
|
352
|
+
clearPrefs() {
|
|
353
|
+
this.prefs = {};
|
|
354
|
+
}
|
|
355
|
+
getPrefsWithPrefix(prefix) {
|
|
356
|
+
const _prefs = {};
|
|
357
|
+
for (const pref in this.prefs) {
|
|
358
|
+
if (pref.startsWith(prefix))
|
|
359
|
+
_prefs[pref] = this.prefs[pref];
|
|
360
|
+
else
|
|
361
|
+
_prefs[`${prefix}.${pref}`] = this.prefs[pref];
|
|
362
|
+
}
|
|
363
|
+
return _prefs;
|
|
364
|
+
}
|
|
365
|
+
getPrefsWithoutPrefix(prefix) {
|
|
366
|
+
const _prefs = {};
|
|
367
|
+
for (const pref in this.prefs) {
|
|
368
|
+
_prefs[pref.replace(`${prefix}.`, "")] = this.prefs[pref];
|
|
369
|
+
}
|
|
370
|
+
return _prefs;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
function renderPluginPrefsDts(prefs, prefix) {
|
|
374
|
+
const dtsContent = `
|
|
375
|
+
/* prettier-ignore */
|
|
376
|
+
/* eslint-disable */
|
|
377
|
+
// @ts-nocheck
|
|
378
|
+
// Generated by zotero-plugin-scaffold
|
|
379
|
+
|
|
380
|
+
type _PluginPrefsMap = {
|
|
381
|
+
${Object.entries(prefs).map(([key, value]) => {
|
|
382
|
+
return `"${key}": ${typeof value};`;
|
|
383
|
+
}).join("\n ")}
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
type PluginPrefKey<K extends keyof _PluginPrefsMap> = \`${prefix}.\${K}\`;
|
|
387
|
+
|
|
388
|
+
type PluginPrefsMap = {
|
|
389
|
+
[K in keyof _PluginPrefsMap as PluginPrefKey<K>]: _PluginPrefsMap[K]
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
declare namespace _ZoteroTypes {
|
|
393
|
+
interface Prefs {
|
|
394
|
+
get: <K extends keyof PluginPrefsMap>(key: K, global?: boolean) => PluginPrefsMap[K];
|
|
395
|
+
set: <K extends keyof PluginPrefsMap>(key: K, value: PluginPrefsMap[K], global?: boolean) => any;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
`;
|
|
399
|
+
return dtsContent;
|
|
400
|
+
}
|
|
401
|
+
|
|
304
402
|
class Base {
|
|
305
403
|
ctx;
|
|
306
404
|
constructor(ctx) {
|
|
@@ -342,6 +440,7 @@ class Build extends Base {
|
|
|
342
440
|
this.logger.debug("Preparing locale files");
|
|
343
441
|
await this.prepareLocaleFiles();
|
|
344
442
|
await this.ctx.hooks.callHook("build:fluent", this.ctx);
|
|
443
|
+
await this.preparePrefs();
|
|
345
444
|
this.logger.tip("Bundling scripts");
|
|
346
445
|
await this.esbuild();
|
|
347
446
|
await this.ctx.hooks.callHook("build:bundle", this.ctx);
|
|
@@ -400,7 +499,6 @@ class Build extends Base {
|
|
|
400
499
|
...version && { version },
|
|
401
500
|
manifest_version: 2,
|
|
402
501
|
applications: {
|
|
403
|
-
// @ts-expect-error 此处不包含版本限制
|
|
404
502
|
zotero: {
|
|
405
503
|
id,
|
|
406
504
|
update_url: updateURL
|
|
@@ -472,6 +570,48 @@ class Build extends Base {
|
|
|
472
570
|
}
|
|
473
571
|
});
|
|
474
572
|
}
|
|
573
|
+
async preparePrefs() {
|
|
574
|
+
const { dts, prefixPrefKeys, prefix } = this.ctx.build.prefs;
|
|
575
|
+
const { dist } = this.ctx;
|
|
576
|
+
if (!prefixPrefKeys && !dts)
|
|
577
|
+
return;
|
|
578
|
+
const prefsFilePath = join(dist, "addon", "prefs.js");
|
|
579
|
+
if (!existsSync(prefsFilePath))
|
|
580
|
+
return;
|
|
581
|
+
const prefsManager = new PrefsManager("pref");
|
|
582
|
+
await prefsManager.read(prefsFilePath);
|
|
583
|
+
const prefsWithPrefix = prefsManager.getPrefsWithPrefix(prefix);
|
|
584
|
+
const prefsWithoutPrefix = prefsManager.getPrefsWithoutPrefix(prefix);
|
|
585
|
+
if (dts) {
|
|
586
|
+
const dtsContent = renderPluginPrefsDts(prefsWithoutPrefix, prefix);
|
|
587
|
+
await outputFile(dts, dtsContent, "utf-8");
|
|
588
|
+
}
|
|
589
|
+
if (prefixPrefKeys) {
|
|
590
|
+
prefsManager.clearPrefs();
|
|
591
|
+
prefsManager.setPrefs(prefsWithPrefix);
|
|
592
|
+
await prefsManager.write(prefsFilePath);
|
|
593
|
+
}
|
|
594
|
+
if (prefixPrefKeys) {
|
|
595
|
+
const HTML_PREFERENCE_PATTERN = new RegExp(`preference="((?!${prefix})\\S*)"`, "g");
|
|
596
|
+
const xhtmlPaths = await glob(`${dist}/addon/**/*.xhtml`);
|
|
597
|
+
await Promise.all(xhtmlPaths.map(async (path) => {
|
|
598
|
+
let content = await readFile(path, "utf-8");
|
|
599
|
+
const matchs = [...content.matchAll(HTML_PREFERENCE_PATTERN)];
|
|
600
|
+
for (const match of matchs) {
|
|
601
|
+
const [matched, key] = match;
|
|
602
|
+
if (!prefsWithoutPrefix[key] && !prefsWithoutPrefix[key]) {
|
|
603
|
+
this.logger.warn(`preference key '${key}' in ${path} not init in prefs.js`);
|
|
604
|
+
continue;
|
|
605
|
+
}
|
|
606
|
+
if (key.startsWith(prefix))
|
|
607
|
+
continue;
|
|
608
|
+
else
|
|
609
|
+
content = content.replace(matched, `preference="${prefix}.${key}"`);
|
|
610
|
+
}
|
|
611
|
+
await outputFile(path, content, "utf-8");
|
|
612
|
+
}));
|
|
613
|
+
}
|
|
614
|
+
}
|
|
475
615
|
esbuild() {
|
|
476
616
|
const { build: { esbuildOptions } } = this.ctx;
|
|
477
617
|
if (esbuildOptions.length === 0)
|
|
@@ -503,7 +643,7 @@ class Build extends Base {
|
|
|
503
643
|
},
|
|
504
644
|
applications: {
|
|
505
645
|
zotero: {
|
|
506
|
-
strict_min_version: min,
|
|
646
|
+
...min && { strict_min_version: min },
|
|
507
647
|
...max && { strict_max_version: max }
|
|
508
648
|
}
|
|
509
649
|
}
|
|
@@ -1176,18 +1316,43 @@ function findFreeTcpPort() {
|
|
|
1176
1316
|
});
|
|
1177
1317
|
}
|
|
1178
1318
|
|
|
1319
|
+
const default_options = {
|
|
1320
|
+
binary: {
|
|
1321
|
+
// path: "",
|
|
1322
|
+
args: [],
|
|
1323
|
+
devtools: true
|
|
1324
|
+
},
|
|
1325
|
+
profile: {
|
|
1326
|
+
path: "./.scaffold/profile",
|
|
1327
|
+
dataDir: "",
|
|
1328
|
+
// keepChanges: true,
|
|
1329
|
+
createIfMissing: true,
|
|
1330
|
+
customPrefs: {}
|
|
1331
|
+
},
|
|
1332
|
+
plugins: {
|
|
1333
|
+
asProxy: false,
|
|
1334
|
+
list: []
|
|
1335
|
+
}
|
|
1336
|
+
};
|
|
1179
1337
|
class ZoteroRunner {
|
|
1180
1338
|
options;
|
|
1181
|
-
remoteFirefox;
|
|
1339
|
+
remoteFirefox = new RemoteFirefox();
|
|
1182
1340
|
zotero;
|
|
1183
1341
|
constructor(options) {
|
|
1184
|
-
this.options = options;
|
|
1185
|
-
|
|
1342
|
+
this.options = toMerged(default_options, options);
|
|
1343
|
+
if (!options.binary.path)
|
|
1344
|
+
throw new Error("Binary path must be provided.");
|
|
1345
|
+
if (!options.profile.path && !options.profile.dataDir)
|
|
1346
|
+
this.options.profile.dataDir = "./.scaffold/data";
|
|
1347
|
+
logger.debug(this.options);
|
|
1348
|
+
}
|
|
1349
|
+
get default_profile_path() {
|
|
1350
|
+
return default_options.profile.path;
|
|
1186
1351
|
}
|
|
1187
1352
|
async run() {
|
|
1188
|
-
await this.
|
|
1353
|
+
await this.setupProfile();
|
|
1189
1354
|
await this.startZoteroInstance();
|
|
1190
|
-
if (!this.options.asProxy)
|
|
1355
|
+
if (!this.options.plugins.asProxy)
|
|
1191
1356
|
await this.installTemporaryPlugins();
|
|
1192
1357
|
}
|
|
1193
1358
|
/**
|
|
@@ -1197,45 +1362,51 @@ class ZoteroRunner {
|
|
|
1197
1362
|
*
|
|
1198
1363
|
* @see https://www.zotero.org/support/dev/client_coding/plugin_development#setting_up_a_plugin_development_environment
|
|
1199
1364
|
*/
|
|
1200
|
-
async
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
});
|
|
1208
|
-
let exsitedPrefs = [];
|
|
1209
|
-
const prefsPath = join(this.options.profilePath, "prefs.js");
|
|
1210
|
-
if (await pathExists(prefsPath)) {
|
|
1211
|
-
const PrefsLines = (await readFile(prefsPath, "utf-8")).split("\n");
|
|
1212
|
-
exsitedPrefs = PrefsLines.map((line) => {
|
|
1213
|
-
if (line.includes("extensions.lastAppBuildId") || line.includes("extensions.lastAppVersion")) {
|
|
1214
|
-
return "";
|
|
1215
|
-
}
|
|
1216
|
-
return line;
|
|
1217
|
-
});
|
|
1365
|
+
async setupProfile() {
|
|
1366
|
+
const { path, createIfMissing } = this.options.profile;
|
|
1367
|
+
if (!await pathExists(path)) {
|
|
1368
|
+
if (createIfMissing)
|
|
1369
|
+
await this.createProfile(this.default_profile_path);
|
|
1370
|
+
else
|
|
1371
|
+
throw new Error("The 'profile.path' must be provided when 'createIfMissing' is false.");
|
|
1218
1372
|
}
|
|
1219
|
-
const
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1373
|
+
const prefsPath = join(this.options.profile.path, "prefs.js");
|
|
1374
|
+
const prefsManager = new PrefsManager("user_pref");
|
|
1375
|
+
prefsManager.setPrefs(prefs);
|
|
1376
|
+
prefsManager.setPrefs(this.options.profile.customPrefs);
|
|
1377
|
+
if (await pathExists(prefsPath))
|
|
1378
|
+
await prefsManager.read(prefsPath);
|
|
1379
|
+
prefsManager.setPrefs({
|
|
1380
|
+
"extensions.lastAppBuildId": null,
|
|
1381
|
+
"extensions.lastAppVersion": null
|
|
1382
|
+
});
|
|
1383
|
+
await prefsManager.write(prefsPath);
|
|
1384
|
+
if (this.options.plugins.asProxy) {
|
|
1223
1385
|
await this.installProxyPlugins();
|
|
1224
1386
|
}
|
|
1225
1387
|
}
|
|
1388
|
+
async createProfile(path) {
|
|
1389
|
+
logger.debug(`Creating profile at ${this.default_profile_path}...`);
|
|
1390
|
+
await ensureDir(path);
|
|
1391
|
+
}
|
|
1392
|
+
// private async copyProfile(from: string, to = this.default_profile_path) {
|
|
1393
|
+
// logger.debug(`Copying profile from '${this.options.profile.path}' to ${this.default_profile_path}...`);
|
|
1394
|
+
// await copy(from, to);
|
|
1395
|
+
// this.options.profile.path = to;
|
|
1396
|
+
// }
|
|
1226
1397
|
async startZoteroInstance() {
|
|
1227
1398
|
let args = ["--purgecaches", "no-remote"];
|
|
1228
|
-
if (this.options.
|
|
1229
|
-
args.push("-profile", resolve(this.options.
|
|
1399
|
+
if (this.options.profile.path) {
|
|
1400
|
+
args.push("-profile", resolve(this.options.profile.path));
|
|
1230
1401
|
}
|
|
1231
|
-
if (this.options.dataDir) {
|
|
1232
|
-
args.push("--dataDir", resolve(this.options.dataDir));
|
|
1402
|
+
if (this.options.profile.dataDir) {
|
|
1403
|
+
args.push("--dataDir", resolve(this.options.profile.dataDir));
|
|
1233
1404
|
}
|
|
1234
|
-
if (this.options.devtools) {
|
|
1405
|
+
if (this.options.binary.devtools) {
|
|
1235
1406
|
args.push("--jsdebugger");
|
|
1236
1407
|
}
|
|
1237
|
-
if (this.options.
|
|
1238
|
-
args = [...args, ...this.options.
|
|
1408
|
+
if (this.options.binary.args) {
|
|
1409
|
+
args = [...args, ...this.options.binary.args];
|
|
1239
1410
|
}
|
|
1240
1411
|
const remotePort = await findFreeTcpPort();
|
|
1241
1412
|
args.push("-start-debugger-server", String(remotePort));
|
|
@@ -1245,7 +1416,9 @@ class ZoteroRunner {
|
|
|
1245
1416
|
XPCOM_DEBUG_BREAK: "stack",
|
|
1246
1417
|
NS_TRACE_MALLOC_DISABLE_STACKS: "1"
|
|
1247
1418
|
};
|
|
1248
|
-
|
|
1419
|
+
if (!await pathExists(this.options.binary.path))
|
|
1420
|
+
throw new Error("The Zotero binary not found.");
|
|
1421
|
+
this.zotero = spawn(this.options.binary.path, args, { env });
|
|
1249
1422
|
logger.debug("Zotero started, pid:", this.zotero.pid);
|
|
1250
1423
|
this.zotero.stdout?.on("data", (_data) => {
|
|
1251
1424
|
});
|
|
@@ -1254,7 +1427,7 @@ class ZoteroRunner {
|
|
|
1254
1427
|
logger.debug(`Connected to the remote Firefox debugger on port: ${remotePort}`);
|
|
1255
1428
|
}
|
|
1256
1429
|
async installTemporaryPlugins() {
|
|
1257
|
-
for (const plugin of this.options.plugins) {
|
|
1430
|
+
for (const plugin of this.options.plugins.list) {
|
|
1258
1431
|
const addonId = await this.remoteFirefox.installTemporaryAddon(resolve(plugin.sourceDir)).then((installResult) => {
|
|
1259
1432
|
return installResult.addon.id;
|
|
1260
1433
|
});
|
|
@@ -1264,7 +1437,7 @@ class ZoteroRunner {
|
|
|
1264
1437
|
}
|
|
1265
1438
|
}
|
|
1266
1439
|
async installProxyPlugin(id, sourceDir) {
|
|
1267
|
-
const addonProxyFilePath = join(this.options.
|
|
1440
|
+
const addonProxyFilePath = join(this.options.profile.path, `extensions/${id}`);
|
|
1268
1441
|
const buildPath = resolve(sourceDir);
|
|
1269
1442
|
await outputFile(addonProxyFilePath, buildPath);
|
|
1270
1443
|
logger.debug(
|
|
@@ -1274,12 +1447,12 @@ class ZoteroRunner {
|
|
|
1274
1447
|
` Addon path: ${buildPath}`
|
|
1275
1448
|
].join("\n")
|
|
1276
1449
|
);
|
|
1277
|
-
const addonXpiFilePath = join(this.options.
|
|
1450
|
+
const addonXpiFilePath = join(this.options.profile.path, `extensions/${id}.xpi`);
|
|
1278
1451
|
if (await pathExists(addonXpiFilePath)) {
|
|
1279
1452
|
await remove(addonXpiFilePath);
|
|
1280
1453
|
logger.debug(`XPI file found, removed.`);
|
|
1281
1454
|
}
|
|
1282
|
-
const addonInfoFilePath = join(this.options.
|
|
1455
|
+
const addonInfoFilePath = join(this.options.profile.path, "extensions.json");
|
|
1283
1456
|
if (await pathExists(addonInfoFilePath)) {
|
|
1284
1457
|
const content = await readJSON(addonInfoFilePath);
|
|
1285
1458
|
content.addons = content.addons.map((addon) => {
|
|
@@ -1294,7 +1467,7 @@ class ZoteroRunner {
|
|
|
1294
1467
|
}
|
|
1295
1468
|
}
|
|
1296
1469
|
async installProxyPlugins() {
|
|
1297
|
-
for (const { id, sourceDir } of this.options.plugins) {
|
|
1470
|
+
for (const { id, sourceDir } of this.options.plugins.list) {
|
|
1298
1471
|
await this.installProxyPlugin(id, sourceDir);
|
|
1299
1472
|
}
|
|
1300
1473
|
}
|
|
@@ -1302,7 +1475,7 @@ class ZoteroRunner {
|
|
|
1302
1475
|
await this.remoteFirefox.reloadAddon(id);
|
|
1303
1476
|
}
|
|
1304
1477
|
async reloadTemporaryPluginBySourceDir(sourceDir) {
|
|
1305
|
-
const addonId = this.options.plugins.find((p) => p.sourceDir === sourceDir)?.id;
|
|
1478
|
+
const addonId = this.options.plugins.list.find((p) => p.sourceDir === sourceDir)?.id;
|
|
1306
1479
|
if (!addonId) {
|
|
1307
1480
|
return {
|
|
1308
1481
|
sourceDir,
|
|
@@ -1322,7 +1495,7 @@ class ZoteroRunner {
|
|
|
1322
1495
|
return { sourceDir, reloadError: void 0 };
|
|
1323
1496
|
}
|
|
1324
1497
|
async reloadAllTemporaryPlugins() {
|
|
1325
|
-
for (const { sourceDir } of this.options.plugins) {
|
|
1498
|
+
for (const { sourceDir } of this.options.plugins.list) {
|
|
1326
1499
|
const res = await this.reloadTemporaryPluginBySourceDir(sourceDir);
|
|
1327
1500
|
if (res.reloadError instanceof Error) {
|
|
1328
1501
|
logger.error(res.reloadError);
|
|
@@ -1349,20 +1522,20 @@ class ZoteroRunner {
|
|
|
1349
1522
|
const url = `zotero://ztoolkit-debug/?run=${encodeURIComponent(
|
|
1350
1523
|
reloadScript
|
|
1351
1524
|
)}`;
|
|
1352
|
-
const startZoteroCmd = `"${this.options.
|
|
1525
|
+
const startZoteroCmd = `"${this.options.binary.path}" --purgecaches -profile "${this.options.profile.path}"`;
|
|
1353
1526
|
const command = `${startZoteroCmd} -url "${url}"`;
|
|
1354
1527
|
execSync(command);
|
|
1355
1528
|
}
|
|
1356
1529
|
// Do not use this method if possible,
|
|
1357
1530
|
// as frequent execSync can cause Zotero to crash.
|
|
1358
1531
|
async reloadAllProxyPlugins() {
|
|
1359
|
-
for (const { id } of this.options.plugins) {
|
|
1532
|
+
for (const { id } of this.options.plugins.list) {
|
|
1360
1533
|
await this.reloadProxyPluginByZToolkit(id, id, id);
|
|
1361
1534
|
await delay(2e3);
|
|
1362
1535
|
}
|
|
1363
1536
|
}
|
|
1364
1537
|
async reloadAllPlugins() {
|
|
1365
|
-
if (this.options.asProxy)
|
|
1538
|
+
if (this.options.plugins.asProxy)
|
|
1366
1539
|
await this.reloadAllProxyPlugins();
|
|
1367
1540
|
else
|
|
1368
1541
|
await this.reloadAllTemporaryPlugins();
|
|
@@ -1401,7 +1574,6 @@ class Serve extends Base {
|
|
|
1401
1574
|
builder;
|
|
1402
1575
|
runner;
|
|
1403
1576
|
_zoteroBinPath;
|
|
1404
|
-
_profilePath;
|
|
1405
1577
|
constructor(ctx) {
|
|
1406
1578
|
super(ctx);
|
|
1407
1579
|
process.env.NODE_ENV ??= "development";
|
|
@@ -1410,20 +1582,30 @@ class Serve extends Base {
|
|
|
1410
1582
|
async run() {
|
|
1411
1583
|
process.on("SIGINT", this.exit);
|
|
1412
1584
|
this.runner = new ZoteroRunner({
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1585
|
+
binary: {
|
|
1586
|
+
path: this.zoteroBinPath,
|
|
1587
|
+
devtools: this.ctx.server.devtools,
|
|
1588
|
+
args: this.ctx.server.startArgs
|
|
1589
|
+
},
|
|
1590
|
+
profile: {
|
|
1591
|
+
path: this.profilePath,
|
|
1592
|
+
dataDir: this.dataDir,
|
|
1593
|
+
// keepChanges: this.ctx.server.keepProfileChanges,
|
|
1594
|
+
createIfMissing: this.ctx.server.createProfileIfMissing
|
|
1595
|
+
},
|
|
1596
|
+
plugins: {
|
|
1597
|
+
list: [{
|
|
1598
|
+
id: this.ctx.id,
|
|
1599
|
+
sourceDir: join(this.ctx.dist, "addon")
|
|
1600
|
+
}],
|
|
1601
|
+
asProxy: this.ctx.server.asProxy
|
|
1602
|
+
}
|
|
1423
1603
|
});
|
|
1424
1604
|
await this.ctx.hooks.callHook("serve:init", this.ctx);
|
|
1425
|
-
|
|
1426
|
-
|
|
1605
|
+
if (this.ctx.server.prebuild) {
|
|
1606
|
+
await this.builder.run();
|
|
1607
|
+
await this.ctx.hooks.callHook("serve:prebuild", this.ctx);
|
|
1608
|
+
}
|
|
1427
1609
|
await this.runner.run();
|
|
1428
1610
|
this.runner.zotero?.on("exit", this.onZoteroExit);
|
|
1429
1611
|
this.runner.zotero?.on("close", this.onZoteroExit);
|
|
@@ -1490,15 +1672,10 @@ class Serve extends Base {
|
|
|
1490
1672
|
return this._zoteroBinPath;
|
|
1491
1673
|
}
|
|
1492
1674
|
get profilePath() {
|
|
1493
|
-
|
|
1494
|
-
return this._profilePath;
|
|
1495
|
-
this._profilePath = process.env.ZOTERO_PLUGIN_PROFILE_PATH;
|
|
1496
|
-
if (!this._profilePath || !existsSync(this._profilePath))
|
|
1497
|
-
throw new Error("The Zotero profile not found.");
|
|
1498
|
-
return this._profilePath;
|
|
1675
|
+
return process.env.ZOTERO_PLUGIN_PROFILE_PATH;
|
|
1499
1676
|
}
|
|
1500
1677
|
get dataDir() {
|
|
1501
|
-
return process.env.ZOTERO_PLUGIN_DATA_DIR
|
|
1678
|
+
return process.env.ZOTERO_PLUGIN_DATA_DIR;
|
|
1502
1679
|
}
|
|
1503
1680
|
}
|
|
1504
1681
|
|
|
@@ -2036,19 +2213,25 @@ class Test extends Base {
|
|
|
2036
2213
|
}
|
|
2037
2214
|
async startZotero() {
|
|
2038
2215
|
this.runner = new ZoteroRunner({
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
}
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2216
|
+
binary: {
|
|
2217
|
+
path: this.zoteroBinPath,
|
|
2218
|
+
devtools: this.ctx.server.devtools,
|
|
2219
|
+
args: this.ctx.server.startArgs
|
|
2220
|
+
},
|
|
2221
|
+
profile: {
|
|
2222
|
+
path: this.profilePath,
|
|
2223
|
+
dataDir: this.dataDir,
|
|
2224
|
+
customPrefs: this.prefs
|
|
2225
|
+
},
|
|
2226
|
+
plugins: {
|
|
2227
|
+
list: [{
|
|
2228
|
+
id: this.ctx.id,
|
|
2229
|
+
sourceDir: join(this.ctx.dist, "addon")
|
|
2230
|
+
}, {
|
|
2231
|
+
id: this.testPluginID,
|
|
2232
|
+
sourceDir: this.testPluginDir
|
|
2233
|
+
}]
|
|
2234
|
+
}
|
|
2052
2235
|
});
|
|
2053
2236
|
await this.runner.run();
|
|
2054
2237
|
}
|
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.15",
|
|
5
5
|
"description": "A scaffold for Zotero plugin development.",
|
|
6
6
|
"author": "northword",
|
|
7
7
|
"license": "AGPL-3.0-or-later",
|
|
@@ -63,13 +63,13 @@
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@commander-js/extra-typings": "^
|
|
66
|
+
"@commander-js/extra-typings": "^13.0.0",
|
|
67
67
|
"adm-zip": "^0.5.16",
|
|
68
68
|
"bumpp": "^9.9.2",
|
|
69
69
|
"c12": "^2.0.1",
|
|
70
70
|
"chalk": "^5.4.1",
|
|
71
71
|
"chokidar": "^4.0.3",
|
|
72
|
-
"commander": "^
|
|
72
|
+
"commander": "^13.0.0",
|
|
73
73
|
"es-toolkit": "^1.31.0",
|
|
74
74
|
"esbuild": "^0.24.2",
|
|
75
75
|
"fs-extra": "^11.2.0",
|