zotero-plugin-scaffold 0.2.0-beta.7 → 0.2.0-beta.9
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 +10 -11
- package/dist/cli.mjs +28 -25
- package/dist/index.d.mts +4 -11
- package/dist/index.d.ts +4 -11
- package/dist/index.mjs +7 -8
- package/dist/shared/{zotero-plugin-scaffold.014fe844.mjs → zotero-plugin-scaffold.2ad7a023.mjs} +130 -195
- package/dist/shared/zotero-plugin-scaffold.77c9802c.mjs +63 -0
- package/dist/vendor/index.d.mts +10 -2
- package/dist/vendor/index.d.ts +10 -2
- package/dist/vendor/index.mjs +3 -2
- package/package.json +3 -5
package/dist/chunks/github.mjs
CHANGED
|
@@ -1,30 +1,29 @@
|
|
|
1
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
1
2
|
import { join, basename } from 'node:path';
|
|
2
3
|
import { env } from 'node:process';
|
|
3
|
-
import fs from 'fs-extra';
|
|
4
|
-
import { globbySync } from 'globby';
|
|
5
4
|
import mime from 'mime';
|
|
6
5
|
import { Octokit } from 'octokit';
|
|
6
|
+
import { globSync, glob } from 'tinyglobby';
|
|
7
7
|
import { isCI } from 'std-env';
|
|
8
|
-
import {
|
|
8
|
+
import { B as Base } from '../shared/zotero-plugin-scaffold.2ad7a023.mjs';
|
|
9
9
|
import 'c12';
|
|
10
10
|
import 'es-toolkit';
|
|
11
|
+
import 'fs-extra/esm';
|
|
11
12
|
import 'hookable';
|
|
12
13
|
import 'node:readline';
|
|
13
14
|
import 'chalk';
|
|
15
|
+
import '../shared/zotero-plugin-scaffold.77c9802c.mjs';
|
|
14
16
|
import 'adm-zip';
|
|
15
17
|
import 'esbuild';
|
|
16
|
-
import 'replace-in-file';
|
|
17
18
|
import 'node:crypto';
|
|
19
|
+
import 'node:fs';
|
|
18
20
|
import 'node:child_process';
|
|
19
21
|
import 'bumpp';
|
|
20
|
-
import 'node:fs';
|
|
21
22
|
import 'chokidar';
|
|
22
|
-
import 'fs-extra/esm';
|
|
23
23
|
import 'node:net';
|
|
24
24
|
import 'node:buffer';
|
|
25
25
|
import 'node:domain';
|
|
26
26
|
import 'node:events';
|
|
27
|
-
import 'node:fs/promises';
|
|
28
27
|
import 'node:http';
|
|
29
28
|
import 'xvfb-ts';
|
|
30
29
|
|
|
@@ -42,7 +41,7 @@ class ReleaseBase extends Base {
|
|
|
42
41
|
}
|
|
43
42
|
checkFiles() {
|
|
44
43
|
const { dist } = this.ctx;
|
|
45
|
-
if (
|
|
44
|
+
if (globSync(`${dist}/*.xpi`).length === 0) {
|
|
46
45
|
throw new Error("No xpi file found, are you sure you have run build?");
|
|
47
46
|
}
|
|
48
47
|
}
|
|
@@ -117,10 +116,10 @@ class GitHub extends ReleaseBase {
|
|
|
117
116
|
return await this.client.rest.repos.uploadReleaseAsset({
|
|
118
117
|
...this.remote,
|
|
119
118
|
release_id: releaseID,
|
|
120
|
-
data:
|
|
119
|
+
data: await readFile(asset),
|
|
121
120
|
headers: {
|
|
122
121
|
"content-type": mime.getType(asset) || "application/octet-stream",
|
|
123
|
-
"content-length":
|
|
122
|
+
"content-length": (await stat(asset)).size
|
|
124
123
|
},
|
|
125
124
|
name: basename(asset)
|
|
126
125
|
}).then((res) => {
|
|
@@ -135,7 +134,7 @@ class GitHub extends ReleaseBase {
|
|
|
135
134
|
return;
|
|
136
135
|
}
|
|
137
136
|
const { dist, version } = this.ctx;
|
|
138
|
-
const assets =
|
|
137
|
+
const assets = (await glob(`${dist}/update*.json`)).map((p) => basename(p));
|
|
139
138
|
const release = await this.getReleaseByTag(updater) ?? await this.createRelease({
|
|
140
139
|
...this.remote,
|
|
141
140
|
tag_name: updater,
|
package/dist/cli.mjs
CHANGED
|
@@ -1,37 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import process, { exit, env } from 'node:process';
|
|
3
3
|
import { Command } from '@commander-js/extra-typings';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import 'node:path';
|
|
4
|
+
import { L as Log, E as ExitSignals, C as Config, a as Build, S as Serve, T as Test, R as Release } from './shared/zotero-plugin-scaffold.2ad7a023.mjs';
|
|
5
|
+
import tinyUpdateNotifier from 'tiny-update-notifier';
|
|
7
6
|
import 'c12';
|
|
8
7
|
import 'es-toolkit';
|
|
9
|
-
import 'fs-extra';
|
|
8
|
+
import 'fs-extra/esm';
|
|
10
9
|
import 'hookable';
|
|
11
10
|
import 'node:readline';
|
|
12
11
|
import 'chalk';
|
|
13
12
|
import 'std-env';
|
|
13
|
+
import './shared/zotero-plugin-scaffold.77c9802c.mjs';
|
|
14
|
+
import 'node:fs/promises';
|
|
15
|
+
import 'tinyglobby';
|
|
16
|
+
import 'node:path';
|
|
14
17
|
import 'adm-zip';
|
|
15
18
|
import 'esbuild';
|
|
16
|
-
import 'globby';
|
|
17
|
-
import 'replace-in-file';
|
|
18
19
|
import 'node:crypto';
|
|
20
|
+
import 'node:fs';
|
|
19
21
|
import 'node:child_process';
|
|
20
22
|
import 'bumpp';
|
|
21
|
-
import 'node:fs';
|
|
22
23
|
import 'chokidar';
|
|
23
|
-
import 'fs-extra/esm';
|
|
24
24
|
import 'node:net';
|
|
25
25
|
import 'node:buffer';
|
|
26
26
|
import 'node:domain';
|
|
27
27
|
import 'node:events';
|
|
28
|
-
import 'node:fs/promises';
|
|
29
28
|
import 'node:http';
|
|
30
29
|
import 'xvfb-ts';
|
|
31
30
|
|
|
32
31
|
const name = "zotero-plugin-scaffold";
|
|
33
32
|
const type = "module";
|
|
34
|
-
const version = "0.2.0-beta.
|
|
33
|
+
const version = "0.2.0-beta.9";
|
|
35
34
|
const packageManager = "pnpm@9.15.0";
|
|
36
35
|
const description = "A scaffold for Zotero plugin development.";
|
|
37
36
|
const author = "northword";
|
|
@@ -109,13 +108,12 @@ const dependencies = {
|
|
|
109
108
|
"es-toolkit": "^1.29.0",
|
|
110
109
|
esbuild: "^0.24.0",
|
|
111
110
|
"fs-extra": "^11.2.0",
|
|
112
|
-
globby: "^14.0.2",
|
|
113
111
|
hookable: "^5.5.3",
|
|
114
112
|
mime: "^4.0.4",
|
|
115
113
|
octokit: "^4.0.2",
|
|
116
|
-
"replace-in-file": "^8.2.0",
|
|
117
114
|
"std-env": "^3.8.0",
|
|
118
|
-
"update-notifier": "^
|
|
115
|
+
"tiny-update-notifier": "^2.0.0",
|
|
116
|
+
tinyglobby: "^0.2.10",
|
|
119
117
|
"xvfb-ts": "^1.1.0"
|
|
120
118
|
};
|
|
121
119
|
const devDependencies = {
|
|
@@ -123,19 +121,11 @@ const devDependencies = {
|
|
|
123
121
|
"@types/adm-zip": "^0.5.7",
|
|
124
122
|
"@types/fs-extra": "^11.0.4",
|
|
125
123
|
"@types/node": "^22.10.2",
|
|
126
|
-
"@types/update-notifier": "^6.0.8",
|
|
127
124
|
eslint: "^9.16.0",
|
|
128
125
|
"eslint-plugin-format": "^0.1.3",
|
|
129
126
|
typescript: "^5.7.2",
|
|
130
127
|
unbuild: "^2.0.0"
|
|
131
128
|
};
|
|
132
|
-
const pnpm = {
|
|
133
|
-
peerDependencyRules: {
|
|
134
|
-
allowAny: [
|
|
135
|
-
"node-fetch"
|
|
136
|
-
]
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
129
|
const pkg = {
|
|
140
130
|
name: name,
|
|
141
131
|
type: type,
|
|
@@ -161,16 +151,29 @@ const pkg = {
|
|
|
161
151
|
peerDependencies: peerDependencies,
|
|
162
152
|
peerDependenciesMeta: peerDependenciesMeta,
|
|
163
153
|
dependencies: dependencies,
|
|
164
|
-
devDependencies: devDependencies
|
|
165
|
-
pnpm: pnpm
|
|
154
|
+
devDependencies: devDependencies
|
|
166
155
|
};
|
|
167
156
|
|
|
157
|
+
const logger$1 = new Log();
|
|
158
|
+
function updateNotifier(name, version) {
|
|
159
|
+
tinyUpdateNotifier({ pkg: { name, version } }).then((update) => {
|
|
160
|
+
if (update) {
|
|
161
|
+
const notify = () => {
|
|
162
|
+
logger$1.newLine();
|
|
163
|
+
logger$1.info(`New version of ${update.name} available!`);
|
|
164
|
+
logger$1.info(`Update: ${update.current} \u2192 ${update.latest} (${update.type})`);
|
|
165
|
+
logger$1.newLine();
|
|
166
|
+
};
|
|
167
|
+
ExitSignals.forEach((sig) => process.once(sig, notify));
|
|
168
|
+
}
|
|
169
|
+
}).catch();
|
|
170
|
+
}
|
|
171
|
+
|
|
168
172
|
const logger = new Log();
|
|
169
173
|
async function main() {
|
|
170
174
|
var _a;
|
|
171
175
|
const { name, version } = pkg;
|
|
172
|
-
updateNotifier(
|
|
173
|
-
process.removeAllListeners("SIGINT");
|
|
176
|
+
updateNotifier(name, version);
|
|
174
177
|
(_a = env).NODE_ENV ?? (_a.NODE_ENV = "development");
|
|
175
178
|
const cli = new Command();
|
|
176
179
|
cli.version(version).usage("<command> [options]");
|
package/dist/index.d.mts
CHANGED
|
@@ -381,7 +381,6 @@ interface BuildHooks {
|
|
|
381
381
|
"build:copyAssets": (ctx: Context) => void | Promise<void>;
|
|
382
382
|
"build:makeManifest": (ctx: Context) => void | Promise<void>;
|
|
383
383
|
"build:fluent": (ctx: Context) => void | Promise<void>;
|
|
384
|
-
"build:replace": (ctx: Context) => void | Promise<void>;
|
|
385
384
|
"build:bundle": (ctx: Context) => void | Promise<void>;
|
|
386
385
|
"build:pack": (ctx: Context) => void | Promise<void>;
|
|
387
386
|
"build:makeUpdateJSON": (ctx: Context) => void | Promise<void>;
|
|
@@ -772,21 +771,15 @@ declare class Build extends Base {
|
|
|
772
771
|
/**
|
|
773
772
|
* Copys files in `Config.build.assets` to `Config.dist`
|
|
774
773
|
*/
|
|
775
|
-
|
|
774
|
+
makeAssets(): Promise<void>;
|
|
776
775
|
/**
|
|
777
776
|
* Override user's manifest
|
|
778
777
|
*
|
|
779
|
-
* Write `applications.gecko` to `manifest.json`
|
|
780
|
-
*
|
|
781
|
-
*/
|
|
782
|
-
makeManifest(): void;
|
|
783
|
-
/**
|
|
784
|
-
* Replace all `placeholder.key` to `placeholder.value` for all files in `dist`
|
|
785
778
|
*/
|
|
786
|
-
|
|
787
|
-
prepareLocaleFiles(): void
|
|
779
|
+
makeManifest(): Promise<void>;
|
|
780
|
+
prepareLocaleFiles(): Promise<void>;
|
|
788
781
|
esbuild(): Promise<esbuild.BuildResult<esbuild.BuildOptions>[]> | undefined;
|
|
789
|
-
makeUpdateJson(): void
|
|
782
|
+
makeUpdateJson(): Promise<void>;
|
|
790
783
|
pack(): Promise<void>;
|
|
791
784
|
}
|
|
792
785
|
|
package/dist/index.d.ts
CHANGED
|
@@ -381,7 +381,6 @@ interface BuildHooks {
|
|
|
381
381
|
"build:copyAssets": (ctx: Context) => void | Promise<void>;
|
|
382
382
|
"build:makeManifest": (ctx: Context) => void | Promise<void>;
|
|
383
383
|
"build:fluent": (ctx: Context) => void | Promise<void>;
|
|
384
|
-
"build:replace": (ctx: Context) => void | Promise<void>;
|
|
385
384
|
"build:bundle": (ctx: Context) => void | Promise<void>;
|
|
386
385
|
"build:pack": (ctx: Context) => void | Promise<void>;
|
|
387
386
|
"build:makeUpdateJSON": (ctx: Context) => void | Promise<void>;
|
|
@@ -772,21 +771,15 @@ declare class Build extends Base {
|
|
|
772
771
|
/**
|
|
773
772
|
* Copys files in `Config.build.assets` to `Config.dist`
|
|
774
773
|
*/
|
|
775
|
-
|
|
774
|
+
makeAssets(): Promise<void>;
|
|
776
775
|
/**
|
|
777
776
|
* Override user's manifest
|
|
778
777
|
*
|
|
779
|
-
* Write `applications.gecko` to `manifest.json`
|
|
780
|
-
*
|
|
781
|
-
*/
|
|
782
|
-
makeManifest(): void;
|
|
783
|
-
/**
|
|
784
|
-
* Replace all `placeholder.key` to `placeholder.value` for all files in `dist`
|
|
785
778
|
*/
|
|
786
|
-
|
|
787
|
-
prepareLocaleFiles(): void
|
|
779
|
+
makeManifest(): Promise<void>;
|
|
780
|
+
prepareLocaleFiles(): Promise<void>;
|
|
788
781
|
esbuild(): Promise<esbuild.BuildResult<esbuild.BuildOptions>[]> | undefined;
|
|
789
|
-
makeUpdateJson(): void
|
|
782
|
+
makeUpdateJson(): Promise<void>;
|
|
790
783
|
pack(): Promise<void>;
|
|
791
784
|
}
|
|
792
785
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
export {
|
|
2
|
-
import 'node:path';
|
|
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.2ad7a023.mjs';
|
|
3
2
|
import 'node:process';
|
|
4
3
|
import 'c12';
|
|
5
4
|
import 'es-toolkit';
|
|
6
|
-
import 'fs-extra';
|
|
5
|
+
import 'fs-extra/esm';
|
|
7
6
|
import 'hookable';
|
|
8
7
|
import 'node:readline';
|
|
9
8
|
import 'chalk';
|
|
10
9
|
import 'std-env';
|
|
10
|
+
import './shared/zotero-plugin-scaffold.77c9802c.mjs';
|
|
11
|
+
import 'node:fs/promises';
|
|
12
|
+
import 'tinyglobby';
|
|
13
|
+
import 'node:path';
|
|
11
14
|
import 'adm-zip';
|
|
12
15
|
import 'esbuild';
|
|
13
|
-
import 'globby';
|
|
14
|
-
import 'replace-in-file';
|
|
15
16
|
import 'node:crypto';
|
|
17
|
+
import 'node:fs';
|
|
16
18
|
import 'node:child_process';
|
|
17
19
|
import 'bumpp';
|
|
18
|
-
import 'node:fs';
|
|
19
20
|
import 'chokidar';
|
|
20
|
-
import 'fs-extra/esm';
|
|
21
21
|
import 'node:net';
|
|
22
22
|
import 'node:buffer';
|
|
23
23
|
import 'node:domain';
|
|
24
24
|
import 'node:events';
|
|
25
|
-
import 'node:fs/promises';
|
|
26
25
|
import 'node:http';
|
|
27
26
|
import 'xvfb-ts';
|
package/dist/shared/{zotero-plugin-scaffold.014fe844.mjs → zotero-plugin-scaffold.2ad7a023.mjs}
RENAMED
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
import path, { join, resolve } from 'node:path';
|
|
2
1
|
import process, { env, platform, exit, cwd } from 'node:process';
|
|
3
2
|
import { loadConfig as loadConfig$1 } from 'c12';
|
|
4
3
|
import { isPlainObject, kebabCase, mapValues, toMerged, escapeRegExp, delay, debounce } from 'es-toolkit';
|
|
5
|
-
import
|
|
4
|
+
import { readJsonSync, emptyDir, copy, readJSON, outputJSON, move, writeJson, pathExists, outputFile, remove, emptyDirSync } from 'fs-extra/esm';
|
|
6
5
|
import { createHooks } from 'hookable';
|
|
7
6
|
import readline from 'node:readline';
|
|
8
7
|
import chalk from 'chalk';
|
|
9
8
|
import { isDebug, isCI, isWindows, isMacOS, isLinux } from 'std-env';
|
|
9
|
+
import { p as parseRepoUrl, d as dateFormat, t as template, a as toArray, r as replaceInFile } from './zotero-plugin-scaffold.77c9802c.mjs';
|
|
10
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
11
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
10
12
|
import AdmZip from 'adm-zip';
|
|
11
13
|
import { build } from 'esbuild';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
14
|
+
import { glob } from 'tinyglobby';
|
|
15
|
+
import { createHash } from 'node:crypto';
|
|
16
|
+
import { createReadStream, existsSync } from 'node:fs';
|
|
15
17
|
import { execSync, spawn } from 'node:child_process';
|
|
16
18
|
import { versionBump, ProgressEvent } from 'bumpp';
|
|
17
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
18
19
|
import chokidar from 'chokidar';
|
|
19
|
-
import { outputFileSync, removeSync, readJSONSync, outputJSONSync, emptyDirSync, outputJSON, outputFile as outputFile$1, pathExists } from 'fs-extra/esm';
|
|
20
20
|
import net from 'node:net';
|
|
21
21
|
import { Buffer } from 'node:buffer';
|
|
22
22
|
import domain from 'node:domain';
|
|
23
23
|
import EventEmitter from 'node:events';
|
|
24
|
-
import { readFile } from 'node:fs/promises';
|
|
25
24
|
import http from 'node:http';
|
|
26
25
|
import { Xvfb } from 'xvfb-ts';
|
|
27
26
|
|
|
@@ -114,46 +113,6 @@ ${arg.stack}`;
|
|
|
114
113
|
}
|
|
115
114
|
}
|
|
116
115
|
|
|
117
|
-
function dateFormat(fmt, date) {
|
|
118
|
-
let ret;
|
|
119
|
-
const opt = {
|
|
120
|
-
"Y+": date.getFullYear().toString(),
|
|
121
|
-
"m+": (date.getMonth() + 1).toString(),
|
|
122
|
-
"d+": date.getDate().toString(),
|
|
123
|
-
"H+": date.getHours().toString(),
|
|
124
|
-
"M+": date.getMinutes().toString(),
|
|
125
|
-
"S+": date.getSeconds().toString()
|
|
126
|
-
};
|
|
127
|
-
for (const k in opt) {
|
|
128
|
-
ret = new RegExp(`(${k})`).exec(fmt);
|
|
129
|
-
if (ret) {
|
|
130
|
-
fmt = fmt.replace(
|
|
131
|
-
ret[1],
|
|
132
|
-
ret[1].length === 1 ? opt[k] : opt[k].padStart(ret[1].length, "0")
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return fmt;
|
|
137
|
-
}
|
|
138
|
-
function toArray(value) {
|
|
139
|
-
return Array.isArray(value) ? value : [value];
|
|
140
|
-
}
|
|
141
|
-
function template(str, data, regex = /\{\{(.+?)\}\}/g) {
|
|
142
|
-
return Array.from(str.matchAll(regex)).reduce((acc, match) => {
|
|
143
|
-
return acc.replace(match[0], data[match[1]]);
|
|
144
|
-
}, str);
|
|
145
|
-
}
|
|
146
|
-
function parseRepoUrl(url) {
|
|
147
|
-
if (!url)
|
|
148
|
-
throw new Error("Parse repository URL failed.");
|
|
149
|
-
const match = url.match(/:\/\/.+com\/([^/]+)\/([^.]+)\.git$/);
|
|
150
|
-
if (!match) {
|
|
151
|
-
throw new Error("Parse repository URL failed.");
|
|
152
|
-
}
|
|
153
|
-
const [, owner, repo] = match;
|
|
154
|
-
return { owner, repo };
|
|
155
|
-
}
|
|
156
|
-
|
|
157
116
|
function defineConfig(userConfig) {
|
|
158
117
|
return userConfig;
|
|
159
118
|
}
|
|
@@ -171,7 +130,7 @@ async function loadConfig(overrides) {
|
|
|
171
130
|
function resolveConfig(config) {
|
|
172
131
|
env.ZOTERO_PLUGIN_LOG_LEVEL = config.logLevel;
|
|
173
132
|
const logger = new Log(config);
|
|
174
|
-
const pkgUser =
|
|
133
|
+
const pkgUser = readJsonSync("package.json", {
|
|
175
134
|
encoding: "utf-8"
|
|
176
135
|
});
|
|
177
136
|
const { name, version } = pkgUser;
|
|
@@ -318,10 +277,21 @@ const defaultConfig = {
|
|
|
318
277
|
};
|
|
319
278
|
const getDefaultConfig = () => defaultConfig;
|
|
320
279
|
|
|
321
|
-
function
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
280
|
+
function generateHash(filePath, algorithm) {
|
|
281
|
+
return new Promise((resolve, reject) => {
|
|
282
|
+
const hash = createHash(algorithm);
|
|
283
|
+
const stream = createReadStream(filePath);
|
|
284
|
+
stream.on("data", (data) => {
|
|
285
|
+
hash.update(data);
|
|
286
|
+
});
|
|
287
|
+
stream.on("end", () => {
|
|
288
|
+
const fileHash = hash.digest("hex");
|
|
289
|
+
resolve(`${algorithm}:${fileHash}`);
|
|
290
|
+
});
|
|
291
|
+
stream.on("error", (error) => {
|
|
292
|
+
reject(error);
|
|
293
|
+
});
|
|
294
|
+
});
|
|
325
295
|
}
|
|
326
296
|
|
|
327
297
|
var __defProp$6 = Object.defineProperty;
|
|
@@ -367,20 +337,17 @@ class Build extends Base {
|
|
|
367
337
|
`Building version ${chalk.blue(version)} to ${chalk.blue(dist)} at ${chalk.blue(this.buildTime)} in ${chalk.blue(env.NODE_ENV)} mode.`
|
|
368
338
|
);
|
|
369
339
|
await this.ctx.hooks.callHook("build:init", this.ctx);
|
|
370
|
-
|
|
340
|
+
await emptyDir(dist);
|
|
371
341
|
await this.ctx.hooks.callHook("build:mkdir", this.ctx);
|
|
372
342
|
this.logger.tip("Preparing static assets");
|
|
373
|
-
this.
|
|
343
|
+
await this.makeAssets();
|
|
374
344
|
await this.ctx.hooks.callHook("build:copyAssets", this.ctx);
|
|
375
345
|
this.logger.debug("Preparing manifest");
|
|
376
|
-
this.makeManifest();
|
|
346
|
+
await this.makeManifest();
|
|
377
347
|
await this.ctx.hooks.callHook("build:makeManifest", this.ctx);
|
|
378
348
|
this.logger.debug("Preparing locale files");
|
|
379
|
-
this.prepareLocaleFiles();
|
|
349
|
+
await this.prepareLocaleFiles();
|
|
380
350
|
await this.ctx.hooks.callHook("build:fluent", this.ctx);
|
|
381
|
-
this.logger.debug("Replacing placeholders");
|
|
382
|
-
this.replaceString();
|
|
383
|
-
await this.ctx.hooks.callHook("build:replace", this.ctx);
|
|
384
351
|
this.logger.tip("Bundling scripts");
|
|
385
352
|
await this.esbuild();
|
|
386
353
|
await this.ctx.hooks.callHook("build:bundle", this.ctx);
|
|
@@ -388,7 +355,7 @@ class Build extends Base {
|
|
|
388
355
|
this.logger.tip("Packing plugin");
|
|
389
356
|
await this.pack();
|
|
390
357
|
await this.ctx.hooks.callHook("build:pack", this.ctx);
|
|
391
|
-
this.makeUpdateJson();
|
|
358
|
+
await this.makeUpdateJson();
|
|
392
359
|
await this.ctx.hooks.callHook("build:makeUpdateJSON", this.ctx);
|
|
393
360
|
}
|
|
394
361
|
await this.ctx.hooks.callHook("build:done", this.ctx);
|
|
@@ -399,27 +366,38 @@ class Build extends Base {
|
|
|
399
366
|
/**
|
|
400
367
|
* Copys files in `Config.build.assets` to `Config.dist`
|
|
401
368
|
*/
|
|
402
|
-
|
|
369
|
+
async makeAssets() {
|
|
403
370
|
const { source, dist, build } = this.ctx;
|
|
404
|
-
const { assets } = build;
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
371
|
+
const { assets, define } = build;
|
|
372
|
+
const paths = await glob(assets, { ignore: ["node_modules", ".git", dist] });
|
|
373
|
+
const newPaths = paths.map((p) => `${dist}/addon/${p.replace(new RegExp(toArray(source).join("|")), "")}`);
|
|
374
|
+
await Promise.all(paths.map(async (file, i) => {
|
|
375
|
+
await copy(file, newPaths[i]);
|
|
376
|
+
this.logger.debug(`Copy ${file} to ${newPaths[i]}`);
|
|
377
|
+
}));
|
|
378
|
+
const replaceMap = new Map(
|
|
379
|
+
Object.keys(define).map((key) => [
|
|
380
|
+
new RegExp(`__${key}__`, "g"),
|
|
381
|
+
define[key]
|
|
382
|
+
])
|
|
383
|
+
);
|
|
384
|
+
this.logger.debug("replace map: ", replaceMap);
|
|
385
|
+
await replaceInFile({
|
|
386
|
+
files: newPaths,
|
|
387
|
+
from: Array.from(replaceMap.keys()),
|
|
388
|
+
to: Array.from(replaceMap.values()),
|
|
389
|
+
isGlob: false
|
|
410
390
|
});
|
|
411
391
|
}
|
|
412
392
|
/**
|
|
413
393
|
* Override user's manifest
|
|
414
394
|
*
|
|
415
|
-
* Write `applications.gecko` to `manifest.json`
|
|
416
|
-
*
|
|
417
395
|
*/
|
|
418
|
-
makeManifest() {
|
|
396
|
+
async makeManifest() {
|
|
419
397
|
if (!this.ctx.build.makeManifest.enable)
|
|
420
398
|
return;
|
|
421
399
|
const { name, id, updateURL, dist, version } = this.ctx;
|
|
422
|
-
const userData =
|
|
400
|
+
const userData = await readJSON(
|
|
423
401
|
`${dist}/addon/manifest.json`
|
|
424
402
|
);
|
|
425
403
|
const template = {
|
|
@@ -437,99 +415,64 @@ class Build extends Base {
|
|
|
437
415
|
};
|
|
438
416
|
const data = toMerged(userData, template);
|
|
439
417
|
this.logger.debug("manifest: ", JSON.stringify(data, null, 2));
|
|
440
|
-
|
|
418
|
+
outputJSON(`${dist}/addon/manifest.json`, data, { spaces: 2 });
|
|
441
419
|
}
|
|
442
|
-
|
|
443
|
-
* Replace all `placeholder.key` to `placeholder.value` for all files in `dist`
|
|
444
|
-
*/
|
|
445
|
-
replaceString() {
|
|
446
|
-
const { dist, build } = this.ctx;
|
|
447
|
-
const { assets, define } = build;
|
|
448
|
-
const replaceMap = new Map(
|
|
449
|
-
Object.keys(define).map((key) => [
|
|
450
|
-
new RegExp(`__${key}__`, "g"),
|
|
451
|
-
define[key]
|
|
452
|
-
])
|
|
453
|
-
);
|
|
454
|
-
this.logger.debug("replace map: ", replaceMap);
|
|
455
|
-
const replaceResult = replaceInFileSync({
|
|
456
|
-
files: toArray(assets).map(
|
|
457
|
-
(asset) => `${dist}/addon/${asset.split("/").slice(1).join("/")}`
|
|
458
|
-
),
|
|
459
|
-
from: Array.from(replaceMap.keys()),
|
|
460
|
-
to: Array.from(replaceMap.values()),
|
|
461
|
-
countMatches: true
|
|
462
|
-
});
|
|
463
|
-
this.logger.debug(
|
|
464
|
-
"Run replace in ",
|
|
465
|
-
replaceResult.filter((f) => f.hasChanged).map((f) => `${f.file} : ${f.numReplacements} / ${f.numMatches}`)
|
|
466
|
-
);
|
|
467
|
-
}
|
|
468
|
-
prepareLocaleFiles() {
|
|
420
|
+
async prepareLocaleFiles() {
|
|
469
421
|
const { dist, namespace, build } = this.ctx;
|
|
470
|
-
const
|
|
422
|
+
const FTL_MESSAGE_PATTERN = /^(?<message>[a-z]\S*)( *= *)(?<pattern>.*)$/gim;
|
|
423
|
+
const HTML_DATAI10NID_PATTERN = new RegExp(`(data-l10n-id)="((?!${namespace})\\S*)"`, "g");
|
|
424
|
+
const localeNames = (await glob(`${dist}/addon/locale/*`, { onlyDirectories: true })).map((locale) => basename(locale));
|
|
471
425
|
this.logger.debug("locale names: ", localeNames);
|
|
426
|
+
const Messages = /* @__PURE__ */ new Map();
|
|
472
427
|
for (const localeName of localeNames) {
|
|
473
|
-
if (build.fluent.prefixLocaleFiles === true) {
|
|
474
|
-
globbySync(`${dist}/addon/locale/${localeName}/**/*.ftl`, {}).forEach((f) => {
|
|
475
|
-
fs.moveSync(
|
|
476
|
-
f,
|
|
477
|
-
`${path.dirname(f)}/${namespace}-${path.basename(f)}`
|
|
478
|
-
);
|
|
479
|
-
this.logger.debug(`Prefix filename: ${f}`);
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
428
|
const MessageInThisLang = /* @__PURE__ */ new Set();
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
});
|
|
499
|
-
return prefixedLines.join("\n");
|
|
429
|
+
const ftlPaths = await glob(`${dist}/addon/locale/${localeName}/**/*.ftl`);
|
|
430
|
+
await Promise.all(ftlPaths.map(async (ftlPath) => {
|
|
431
|
+
const ftlContent = await readFile(ftlPath, "utf-8");
|
|
432
|
+
const matchs = [...ftlContent.matchAll(FTL_MESSAGE_PATTERN)];
|
|
433
|
+
const newFtlContent = matchs.reduce((content, match) => {
|
|
434
|
+
if (!match.groups?.message)
|
|
435
|
+
return content;
|
|
436
|
+
MessageInThisLang.add(match.groups.message);
|
|
437
|
+
return content.replace(match.groups.message, `${namespace}-${match.groups.message}`);
|
|
438
|
+
}, ftlContent);
|
|
439
|
+
if (build.fluent.prefixFluentMessages)
|
|
440
|
+
await writeFile(ftlPath, newFtlContent);
|
|
441
|
+
if (build.fluent.prefixLocaleFiles === true) {
|
|
442
|
+
await move(ftlPath, `${dirname(ftlPath)}/${namespace}-${basename(ftlPath)}`);
|
|
443
|
+
this.logger.debug(`Prefix filename: ${ftlPath}`);
|
|
500
444
|
}
|
|
501
|
-
});
|
|
502
|
-
|
|
503
|
-
replaceInFileSync({
|
|
504
|
-
files: [
|
|
505
|
-
`${dist}/addon/**/*.xhtml`,
|
|
506
|
-
`${dist}/addon/**/*.html`
|
|
507
|
-
],
|
|
508
|
-
processor: (input) => {
|
|
509
|
-
const matches = [
|
|
510
|
-
...input.matchAll(
|
|
511
|
-
new RegExp(`(data-l10n-id)="((?!${namespace})\\S*)"`, "g")
|
|
512
|
-
)
|
|
513
|
-
];
|
|
514
|
-
matches.forEach((match) => {
|
|
515
|
-
const [matched, attrKey, attrVal] = match;
|
|
516
|
-
if (!MessageInThisLang.has(attrVal)) {
|
|
517
|
-
this.logger.warn(`${attrVal} don't exist in ${localeName}`);
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
if (!this.ctx.build.fluent.prefixFluentMessages) {
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
input = input.replace(
|
|
524
|
-
matched,
|
|
525
|
-
`${attrKey}="${namespace}-${attrVal}"`
|
|
526
|
-
);
|
|
527
|
-
MessagesInHTML.add(attrVal);
|
|
528
|
-
});
|
|
529
|
-
return input;
|
|
530
|
-
}
|
|
531
|
-
});
|
|
445
|
+
}));
|
|
446
|
+
Messages.set(localeName, MessageInThisLang);
|
|
532
447
|
}
|
|
448
|
+
const MessagesInHTML = /* @__PURE__ */ new Set();
|
|
449
|
+
const htmlPaths = await glob([
|
|
450
|
+
`${dist}/addon/**/*.xhtml`,
|
|
451
|
+
`${dist}/addon/**/*.html`
|
|
452
|
+
]);
|
|
453
|
+
await Promise.all(htmlPaths.map(async (htmlPath) => {
|
|
454
|
+
const content = await readFile(htmlPath, "utf-8");
|
|
455
|
+
const matches = [...content.matchAll(HTML_DATAI10NID_PATTERN)];
|
|
456
|
+
const newHtmlContent = matches.reduce((result, match) => {
|
|
457
|
+
const [matched, attrKey, attrVal] = match;
|
|
458
|
+
MessagesInHTML.add(attrVal);
|
|
459
|
+
return result.replace(
|
|
460
|
+
matched,
|
|
461
|
+
`${attrKey}="${namespace}-${attrVal}"`
|
|
462
|
+
);
|
|
463
|
+
}, content);
|
|
464
|
+
if (build.fluent.prefixFluentMessages)
|
|
465
|
+
await writeFile(htmlPath, newHtmlContent);
|
|
466
|
+
}));
|
|
467
|
+
MessagesInHTML.forEach((messageInHTML) => {
|
|
468
|
+
const miss = /* @__PURE__ */ new Set();
|
|
469
|
+
Messages.forEach((messagesInThisLang, lang) => {
|
|
470
|
+
if (!messagesInThisLang.has(messageInHTML))
|
|
471
|
+
miss.add(lang);
|
|
472
|
+
});
|
|
473
|
+
if (miss.size !== 0)
|
|
474
|
+
this.logger.warn(`FTL message "${messageInHTML}" don't exist in "${[...miss].join(", ")}"`);
|
|
475
|
+
});
|
|
533
476
|
}
|
|
534
477
|
esbuild() {
|
|
535
478
|
const { build: { esbuildOptions } } = this.ctx;
|
|
@@ -541,17 +484,14 @@ class Build extends Base {
|
|
|
541
484
|
)
|
|
542
485
|
);
|
|
543
486
|
}
|
|
544
|
-
makeUpdateJson() {
|
|
487
|
+
async makeUpdateJson() {
|
|
545
488
|
const { dist, xpiName, id, version, xpiDownloadLink, build } = this.ctx;
|
|
546
|
-
const manifest =
|
|
489
|
+
const manifest = await readJSON(
|
|
547
490
|
`${dist}/addon/manifest.json`
|
|
548
491
|
);
|
|
549
492
|
const min = manifest.applications?.zotero?.strict_min_version;
|
|
550
493
|
const max = manifest.applications?.zotero?.strict_max_version;
|
|
551
|
-
const updateHash =
|
|
552
|
-
path.join(dist, `${xpiName}.xpi`),
|
|
553
|
-
"sha512"
|
|
554
|
-
);
|
|
494
|
+
const updateHash = await generateHash(`${dist}/${xpiName}.xpi`, "sha512");
|
|
555
495
|
const data = {
|
|
556
496
|
addons: {
|
|
557
497
|
[id]: {
|
|
@@ -574,9 +514,9 @@ class Build extends Base {
|
|
|
574
514
|
}
|
|
575
515
|
}
|
|
576
516
|
};
|
|
577
|
-
|
|
517
|
+
await writeJson(`${dist}/update-beta.json`, data, { spaces: 2 });
|
|
578
518
|
if (!this.isPreRelease)
|
|
579
|
-
|
|
519
|
+
await writeJson(`${dist}/update.json`, data, { spaces: 2 });
|
|
580
520
|
this.logger.debug(
|
|
581
521
|
`Prepare Update.json for ${this.isPreRelease ? "\x1B[31m Prerelease \x1B[0m" : "\x1B[32m Release \x1B[0m"}`
|
|
582
522
|
);
|
|
@@ -584,11 +524,7 @@ class Build extends Base {
|
|
|
584
524
|
async pack() {
|
|
585
525
|
const { dist, xpiName } = this.ctx;
|
|
586
526
|
const zip = new AdmZip();
|
|
587
|
-
|
|
588
|
-
paths.forEach((relativePath) => {
|
|
589
|
-
const absolutePath = path.resolve(`${dist}/addon`, relativePath);
|
|
590
|
-
zip.addLocalFile(absolutePath, path.dirname(relativePath));
|
|
591
|
-
});
|
|
527
|
+
zip.addLocalFolder(`${dist}/addon`);
|
|
592
528
|
zip.writeZip(`${dist}/${xpiName}.xpi`);
|
|
593
529
|
}
|
|
594
530
|
}
|
|
@@ -800,6 +736,7 @@ function isRunning(query) {
|
|
|
800
736
|
return false;
|
|
801
737
|
}
|
|
802
738
|
}
|
|
739
|
+
const ExitSignals = ["exit", "SIGABRT", "SIGALRM", "SIGHUP", "SIGINT", "SIGTERM"];
|
|
803
740
|
|
|
804
741
|
const prefsCommon = {
|
|
805
742
|
// Allow debug output via dump to be printed to the system console
|
|
@@ -1293,8 +1230,8 @@ class ZoteroRunner {
|
|
|
1293
1230
|
});
|
|
1294
1231
|
let exsitedPrefs = [];
|
|
1295
1232
|
const prefsPath = join(this.options.profilePath, "prefs.js");
|
|
1296
|
-
if (
|
|
1297
|
-
const PrefsLines =
|
|
1233
|
+
if (await pathExists(prefsPath)) {
|
|
1234
|
+
const PrefsLines = (await readFile(prefsPath, "utf-8")).split("\n");
|
|
1298
1235
|
exsitedPrefs = PrefsLines.map((line) => {
|
|
1299
1236
|
if (line.includes("extensions.lastAppBuildId") || line.includes("extensions.lastAppVersion")) {
|
|
1300
1237
|
return "";
|
|
@@ -1306,7 +1243,7 @@ class ZoteroRunner {
|
|
|
1306
1243
|
});
|
|
1307
1244
|
}
|
|
1308
1245
|
const updatedPrefs = [...defaultPrefs, ...exsitedPrefs, ...customPrefs].join("\n");
|
|
1309
|
-
|
|
1246
|
+
await outputFile(prefsPath, updatedPrefs, "utf-8");
|
|
1310
1247
|
logger$1.debug("The <profile>/prefs.js has been modified.");
|
|
1311
1248
|
if (this.options.asProxy) {
|
|
1312
1249
|
await this.installProxyPlugins();
|
|
@@ -1353,24 +1290,22 @@ class ZoteroRunner {
|
|
|
1353
1290
|
async installProxyPlugin(id, sourceDir) {
|
|
1354
1291
|
const addonProxyFilePath = join(this.options.profilePath, `extensions/${id}`);
|
|
1355
1292
|
const buildPath = resolve(sourceDir);
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
);
|
|
1365
|
-
}
|
|
1293
|
+
await outputFile(addonProxyFilePath, buildPath);
|
|
1294
|
+
logger$1.debug(
|
|
1295
|
+
[
|
|
1296
|
+
`Addon proxy file has been updated.`,
|
|
1297
|
+
` File path: ${addonProxyFilePath}`,
|
|
1298
|
+
` Addon path: ${buildPath}`
|
|
1299
|
+
].join("\n")
|
|
1300
|
+
);
|
|
1366
1301
|
const addonXpiFilePath = join(this.options.profilePath, `extensions/${id}.xpi`);
|
|
1367
|
-
if (
|
|
1368
|
-
|
|
1302
|
+
if (await pathExists(addonXpiFilePath)) {
|
|
1303
|
+
await remove(addonXpiFilePath);
|
|
1369
1304
|
logger$1.debug(`XPI file found, removed.`);
|
|
1370
1305
|
}
|
|
1371
1306
|
const addonInfoFilePath = join(this.options.profilePath, "extensions.json");
|
|
1372
|
-
if (
|
|
1373
|
-
const content =
|
|
1307
|
+
if (await pathExists(addonInfoFilePath)) {
|
|
1308
|
+
const content = await readJSON(addonInfoFilePath);
|
|
1374
1309
|
content.addons = content.addons.map((addon) => {
|
|
1375
1310
|
if (addon.id === id && addon.active === false) {
|
|
1376
1311
|
addon.active = true;
|
|
@@ -1379,7 +1314,7 @@ class ZoteroRunner {
|
|
|
1379
1314
|
}
|
|
1380
1315
|
return addon;
|
|
1381
1316
|
});
|
|
1382
|
-
|
|
1317
|
+
await outputJSON(addonInfoFilePath, content);
|
|
1383
1318
|
}
|
|
1384
1319
|
}
|
|
1385
1320
|
async installProxyPlugins() {
|
|
@@ -1821,7 +1756,7 @@ function waitUtilAsync(condition, interval = 100, timeout = 1e4) {
|
|
|
1821
1756
|
* End of code added by the zotero-plugin-scaffold test runner
|
|
1822
1757
|
*/
|
|
1823
1758
|
`;
|
|
1824
|
-
|
|
1759
|
+
await outputFile(`${this.testPluginDir}/bootstrap.js`, code);
|
|
1825
1760
|
this.logger.tip("Saved bootstrap.js for test");
|
|
1826
1761
|
}
|
|
1827
1762
|
async createTestResources() {
|
|
@@ -1857,7 +1792,7 @@ function waitUtilAsync(condition, interval = 100, timeout = 1e4) {
|
|
|
1857
1792
|
</body>
|
|
1858
1793
|
</html>
|
|
1859
1794
|
`;
|
|
1860
|
-
await outputFile
|
|
1795
|
+
await outputFile(`${this.testPluginDir}/content/index.xhtml`, html);
|
|
1861
1796
|
this.logger.tip("Saved test resources");
|
|
1862
1797
|
}
|
|
1863
1798
|
async bundleTests() {
|
|
@@ -1868,14 +1803,14 @@ function waitUtilAsync(condition, interval = 100, timeout = 1e4) {
|
|
|
1868
1803
|
tsconfigPath = void 0;
|
|
1869
1804
|
}
|
|
1870
1805
|
await build({
|
|
1871
|
-
entryPoints:
|
|
1806
|
+
entryPoints: await glob(`${dir}/**/*.spec.{js,ts}`),
|
|
1872
1807
|
outdir: this.testBuildDir,
|
|
1873
1808
|
bundle: true,
|
|
1874
1809
|
target: "firefox115",
|
|
1875
1810
|
tsconfig: tsconfigPath || void 0
|
|
1876
1811
|
});
|
|
1877
1812
|
}
|
|
1878
|
-
const testFiles =
|
|
1813
|
+
const testFiles = await glob(`${this.testBuildDir}/**/*.spec.js`);
|
|
1879
1814
|
testFiles.sort();
|
|
1880
1815
|
let testCode = `
|
|
1881
1816
|
mocha.setup({ ui: "bdd", reporter: Reporter, timeout: ${this.ctx.test.mocha.timeout} || 10000, });
|
|
@@ -2032,7 +1967,7 @@ ${code}
|
|
|
2032
1967
|
testCode += `
|
|
2033
1968
|
mocha.run();
|
|
2034
1969
|
`;
|
|
2035
|
-
await outputFile
|
|
1970
|
+
await outputFile(`${this.testPluginDir}/content/index.spec.js`, testCode);
|
|
2036
1971
|
this.logger.tip(`Injected ${testFiles.length} test files`);
|
|
2037
1972
|
}
|
|
2038
1973
|
async startTestServer() {
|
|
@@ -2187,4 +2122,4 @@ const Config = {
|
|
|
2187
2122
|
loadConfig
|
|
2188
2123
|
};
|
|
2189
2124
|
|
|
2190
|
-
export {
|
|
2125
|
+
export { Base as B, Config as C, ExitSignals as E, Log as L, Release as R, Serve as S, Test as T, Build as a, defineConfig as d };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { glob } from 'tinyglobby';
|
|
3
|
+
import 'es-toolkit';
|
|
4
|
+
import 'fs-extra/esm';
|
|
5
|
+
|
|
6
|
+
function dateFormat(fmt, date) {
|
|
7
|
+
let ret;
|
|
8
|
+
const opt = {
|
|
9
|
+
"Y+": date.getFullYear().toString(),
|
|
10
|
+
"m+": (date.getMonth() + 1).toString(),
|
|
11
|
+
"d+": date.getDate().toString(),
|
|
12
|
+
"H+": date.getHours().toString(),
|
|
13
|
+
"M+": date.getMinutes().toString(),
|
|
14
|
+
"S+": date.getSeconds().toString()
|
|
15
|
+
};
|
|
16
|
+
for (const k in opt) {
|
|
17
|
+
ret = new RegExp(`(${k})`).exec(fmt);
|
|
18
|
+
if (ret) {
|
|
19
|
+
fmt = fmt.replace(
|
|
20
|
+
ret[1],
|
|
21
|
+
ret[1].length === 1 ? opt[k] : opt[k].padStart(ret[1].length, "0")
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return fmt;
|
|
26
|
+
}
|
|
27
|
+
function toArray(value) {
|
|
28
|
+
return Array.isArray(value) ? value : [value];
|
|
29
|
+
}
|
|
30
|
+
function template(str, data, regex = /\{\{(.+?)\}\}/g) {
|
|
31
|
+
return Array.from(str.matchAll(regex)).reduce((acc, match) => {
|
|
32
|
+
return acc.replace(match[0], data[match[1]]);
|
|
33
|
+
}, str);
|
|
34
|
+
}
|
|
35
|
+
function parseRepoUrl(url) {
|
|
36
|
+
if (!url)
|
|
37
|
+
throw new Error("Parse repository URL failed.");
|
|
38
|
+
const match = url.match(/:\/\/.+com\/([^/]+)\/([^.]+)\.git$/);
|
|
39
|
+
if (!match) {
|
|
40
|
+
throw new Error("Parse repository URL failed.");
|
|
41
|
+
}
|
|
42
|
+
const [, owner, repo] = match;
|
|
43
|
+
return { owner, repo };
|
|
44
|
+
}
|
|
45
|
+
function replace(contents, from, to) {
|
|
46
|
+
const froms = Array.isArray(from) ? from : [from];
|
|
47
|
+
const tos = Array.isArray(to) ? to : Array.from({ length: froms.length }, () => to);
|
|
48
|
+
if (froms.length !== tos.length) {
|
|
49
|
+
throw new Error("The lengths of 'from' and 'to' must be equal");
|
|
50
|
+
}
|
|
51
|
+
return froms.reduce((result, pattern, index) => result.replace(pattern, tos[index]), contents);
|
|
52
|
+
}
|
|
53
|
+
async function replaceInFile({ files, from, to, isGlob = true }) {
|
|
54
|
+
const paths = isGlob ? await glob(files) : toArray(files);
|
|
55
|
+
await Promise.all(paths.map(async (path) => {
|
|
56
|
+
const contents = await readFile(path, "utf-8");
|
|
57
|
+
const newContents = replace(contents, from, to);
|
|
58
|
+
if (contents !== newContents)
|
|
59
|
+
await writeFile(path, newContents);
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { toArray as a, replace as b, dateFormat as d, parseRepoUrl as p, replaceInFile as r, template as t };
|
package/dist/vendor/index.d.mts
CHANGED
|
@@ -2,5 +2,13 @@ import * as esToolkit from 'es-toolkit';
|
|
|
2
2
|
export { esToolkit };
|
|
3
3
|
import * as esm from 'fs-extra/esm';
|
|
4
4
|
export { esm as fse };
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
|
|
6
|
+
declare function replace(contents: string, from: RegExp | RegExp[], to: string | string[]): string;
|
|
7
|
+
declare function replaceInFile({ files, from, to, isGlob }: {
|
|
8
|
+
files: string | string[];
|
|
9
|
+
from: RegExp | RegExp[];
|
|
10
|
+
to: string | string[];
|
|
11
|
+
isGlob?: boolean;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
|
|
14
|
+
export { replace, replaceInFile };
|
package/dist/vendor/index.d.ts
CHANGED
|
@@ -2,5 +2,13 @@ import * as esToolkit from 'es-toolkit';
|
|
|
2
2
|
export { esToolkit };
|
|
3
3
|
import * as esm from 'fs-extra/esm';
|
|
4
4
|
export { esm as fse };
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
|
|
6
|
+
declare function replace(contents: string, from: RegExp | RegExp[], to: string | string[]): string;
|
|
7
|
+
declare function replaceInFile({ files, from, to, isGlob }: {
|
|
8
|
+
files: string | string[];
|
|
9
|
+
from: RegExp | RegExp[];
|
|
10
|
+
to: string | string[];
|
|
11
|
+
isGlob?: boolean;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
|
|
14
|
+
export { replace, replaceInFile };
|
package/dist/vendor/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
export { b as replace, r as replaceInFile } from '../shared/zotero-plugin-scaffold.77c9802c.mjs';
|
|
1
2
|
import * as esToolkit from 'es-toolkit';
|
|
2
3
|
export { esToolkit };
|
|
3
4
|
import * as esm from 'fs-extra/esm';
|
|
4
5
|
export { esm as fse };
|
|
5
|
-
import
|
|
6
|
-
|
|
6
|
+
import 'node:fs/promises';
|
|
7
|
+
import 'tinyglobby';
|
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.9",
|
|
5
5
|
"description": "A scaffold for Zotero plugin development.",
|
|
6
6
|
"author": "northword",
|
|
7
7
|
"license": "AGPL-3.0-or-later",
|
|
@@ -69,13 +69,12 @@
|
|
|
69
69
|
"es-toolkit": "^1.29.0",
|
|
70
70
|
"esbuild": "^0.24.0",
|
|
71
71
|
"fs-extra": "^11.2.0",
|
|
72
|
-
"globby": "^14.0.2",
|
|
73
72
|
"hookable": "^5.5.3",
|
|
74
73
|
"mime": "^4.0.4",
|
|
75
74
|
"octokit": "^4.0.2",
|
|
76
|
-
"replace-in-file": "^8.2.0",
|
|
77
75
|
"std-env": "^3.8.0",
|
|
78
|
-
"update-notifier": "^
|
|
76
|
+
"tiny-update-notifier": "^2.0.0",
|
|
77
|
+
"tinyglobby": "^0.2.10",
|
|
79
78
|
"xvfb-ts": "^1.1.0"
|
|
80
79
|
},
|
|
81
80
|
"devDependencies": {
|
|
@@ -83,7 +82,6 @@
|
|
|
83
82
|
"@types/adm-zip": "^0.5.7",
|
|
84
83
|
"@types/fs-extra": "^11.0.4",
|
|
85
84
|
"@types/node": "^22.10.2",
|
|
86
|
-
"@types/update-notifier": "^6.0.8",
|
|
87
85
|
"eslint": "^9.16.0",
|
|
88
86
|
"eslint-plugin-format": "^0.1.3",
|
|
89
87
|
"typescript": "^5.7.2",
|