zotero-plugin-scaffold 0.1.3 → 0.1.5

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.
@@ -0,0 +1,127 @@
1
+ import fs from 'node:fs';
2
+ import { join, basename } from 'node:path';
3
+ import { env } from 'node:process';
4
+ import { OpenAPI, RepositoriesService } from '@gitee/typescript-sdk-v5';
5
+ import { globbySync } from 'globby';
6
+ import { R as ReleaseBase } from '../shared/zotero-plugin-scaffold.3e58ced7.mjs';
7
+ import 'std-env';
8
+ import '../shared/zotero-plugin-scaffold.c7c8af0c.mjs';
9
+ import 'c12';
10
+ import 'es-toolkit';
11
+ import 'fs-extra';
12
+ import 'hookable';
13
+ import 'node:readline';
14
+ import 'chalk';
15
+ import 'esbuild';
16
+ import 'replace-in-file';
17
+ import 'web-ext';
18
+ import 'node:crypto';
19
+ import 'node:child_process';
20
+ import 'conventional-changelog';
21
+ import 'bumpp';
22
+ import 'chokidar';
23
+
24
+ var __defProp = Object.defineProperty;
25
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
26
+ var __publicField = (obj, key, value) => {
27
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
28
+ return value;
29
+ };
30
+ class Gitee extends ReleaseBase {
31
+ constructor() {
32
+ super(...arguments);
33
+ __publicField(this, "client", RepositoriesService);
34
+ }
35
+ async run() {
36
+ OpenAPI.TOKEN = env.GITEE_TOKEN;
37
+ if (!OpenAPI.TOKEN)
38
+ throw new Error("No GITEE_TOKEN provided!");
39
+ this.checkFiles();
40
+ this.logger.info("Uploading XPI to Gitee...");
41
+ await this.uploadXPI();
42
+ this.logger.info("Refreshing update manifest...");
43
+ await this.refreshUpdateManifest();
44
+ }
45
+ async uploadXPI() {
46
+ const { version, dist, xpiName } = this.ctx;
47
+ const release = await this.refreshRelease(
48
+ this.ctx.release.bumpp.tag.toString().replaceAll("%s", version),
49
+ `Release v${version}`,
50
+ this.ctx.release.gitee.releaseNote(this.ctx)
51
+ );
52
+ await this.refreshAttach(release.id, join(dist, `${xpiName}.xpi`));
53
+ }
54
+ async refreshUpdateManifest() {
55
+ const updater = this.ctx.release.gitee.updater;
56
+ if (!updater) {
57
+ this.logger.debug(
58
+ `Skip refresh update.json because release.gitee.updater = false`
59
+ );
60
+ return;
61
+ }
62
+ const { dist, version } = this.ctx;
63
+ const assets = globbySync(`${dist}/update*.json`).map((p) => basename(p));
64
+ const release = await this.refreshRelease(
65
+ updater,
66
+ "Zotero Auto Update Manifest",
67
+ `This release is used to host \`update.json\`, Updated in UTC ${( new Date()).toISOString()} for v${version}.`,
68
+ true
69
+ );
70
+ for (const asset of assets)
71
+ await this.refreshAttach(release.id, join(dist, asset));
72
+ }
73
+ async refreshRelease(tag, name, body, prerelease = false) {
74
+ const old = await this.client.getV5ReposOwnerRepoReleasesTagsTag({
75
+ ...this.remote,
76
+ tag
77
+ });
78
+ if (old?.id) {
79
+ return this.client.patchV5ReposOwnerRepoReleasesId({
80
+ ...this.remote,
81
+ name,
82
+ body,
83
+ prerelease,
84
+ id: old.id,
85
+ tagName: tag
86
+ });
87
+ }
88
+ return this.client.postV5ReposOwnerRepoReleases({
89
+ ...this.remote,
90
+ name,
91
+ body,
92
+ prerelease,
93
+ tagName: tag,
94
+ targetCommitish: "main"
95
+ });
96
+ }
97
+ async refreshAttach(releaseId, file) {
98
+ const assets = await this.client.getV5ReposOwnerRepoReleasesReleaseIdAttachFiles({
99
+ ...this.remote,
100
+ releaseId
101
+ });
102
+ const fileBuffer = fs.readFileSync(file);
103
+ for (const asset of assets) {
104
+ if (asset.name === basename(file)) {
105
+ await this.client.deleteV5ReposOwnerRepoReleasesReleaseIdAttachFilesAttachFileId({
106
+ ...this.remote,
107
+ releaseId,
108
+ attachFileId: asset.id
109
+ }).catch((e) => this.logger.error(e));
110
+ }
111
+ }
112
+ this.client.postV5ReposOwnerRepoReleasesReleaseIdAttachFiles({
113
+ ...this.remote,
114
+ releaseId,
115
+ file: new File([fileBuffer], basename(file), { type: "application/octet-stream" })
116
+ });
117
+ }
118
+ get remote() {
119
+ const [owner, repo] = this.ctx.release.gitee.repository.split("/");
120
+ return {
121
+ owner,
122
+ repo
123
+ };
124
+ }
125
+ }
126
+
127
+ export { Gitee as default };
@@ -0,0 +1,175 @@
1
+ import { join, basename } from 'node:path';
2
+ import { env } from 'node:process';
3
+ import fs from 'fs-extra';
4
+ import { globbySync } from 'globby';
5
+ import mime from 'mime';
6
+ import { Octokit } from 'octokit';
7
+ import { R as ReleaseBase } from '../shared/zotero-plugin-scaffold.3e58ced7.mjs';
8
+ import 'std-env';
9
+ import '../shared/zotero-plugin-scaffold.c7c8af0c.mjs';
10
+ import 'c12';
11
+ import 'es-toolkit';
12
+ import 'hookable';
13
+ import 'node:readline';
14
+ import 'chalk';
15
+ import 'esbuild';
16
+ import 'replace-in-file';
17
+ import 'web-ext';
18
+ import 'node:crypto';
19
+ import 'node:child_process';
20
+ import 'conventional-changelog';
21
+ import 'bumpp';
22
+ import 'chokidar';
23
+ import 'node:fs';
24
+
25
+ var __defProp = Object.defineProperty;
26
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
27
+ var __publicField = (obj, key, value) => {
28
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
29
+ return value;
30
+ };
31
+ class GitHub extends ReleaseBase {
32
+ constructor(ctx) {
33
+ super(ctx);
34
+ __publicField(this, "client");
35
+ this.client = this.getClient();
36
+ }
37
+ async run() {
38
+ this.checkFiles();
39
+ this.logger.info("Uploading XPI to GitHub...");
40
+ await this.uploadXPI();
41
+ this.logger.info("Refreshing update manifest...");
42
+ await this.refreshUpdateManifest();
43
+ return this.ctx;
44
+ }
45
+ /**
46
+ * Create new release and upload XPI to asset
47
+ */
48
+ async uploadXPI() {
49
+ const { version, dist, xpiName } = this.ctx;
50
+ const release = await this.createRelease({
51
+ ...this.remote,
52
+ tag_name: this.ctx.release.bumpp.tag.toString().replaceAll("%s", version),
53
+ name: `Release v${version}`,
54
+ body: await this.getChangelog(),
55
+ prerelease: version.includes("-"),
56
+ make_latest: "true"
57
+ });
58
+ if (!release)
59
+ throw new Error("Create release failed!");
60
+ this.logger.debug("Uploading xpi asset...");
61
+ await this.uploadAsset(release.id, join(dist, `${xpiName}.xpi`));
62
+ }
63
+ async getReleaseByTag(tag) {
64
+ return await this.client.rest.repos.getReleaseByTag({
65
+ ...this.remote,
66
+ tag
67
+ }).catch((e) => {
68
+ this.logger.debug(`Release with tag ${tag} not found. ${e}`);
69
+ return void 0;
70
+ }).then((res) => {
71
+ if (res && res.status === 200) {
72
+ this.logger.debug(`Found release with tag "${tag}", id=${res.data.id}.`);
73
+ return res.data;
74
+ }
75
+ });
76
+ }
77
+ async createRelease(options) {
78
+ this.logger.debug("Creating release...", options);
79
+ return await this.client.rest.repos.createRelease(options).catch((e) => {
80
+ this.logger.error(e);
81
+ throw new Error("Create release failed.");
82
+ }).then((res) => {
83
+ if (res.status === 201) {
84
+ this.logger.debug(`Create release "${res.data.tag_name}" success, id: ${res.data.id}.`);
85
+ return res.data;
86
+ }
87
+ });
88
+ }
89
+ async uploadAsset(releaseID, asset) {
90
+ this.logger.debug(`Uploading ${asset} to release ${releaseID}`);
91
+ return await this.client.rest.repos.uploadReleaseAsset({
92
+ ...this.remote,
93
+ release_id: releaseID,
94
+ data: fs.readFileSync(asset),
95
+ headers: {
96
+ "content-type": mime.getType(asset) || "application/octet-stream",
97
+ "content-length": fs.statSync(asset).size
98
+ },
99
+ name: basename(asset)
100
+ }).then((res) => {
101
+ this.logger.debug(`Upload "${res.data.name}" success, assetId: ${res.data.id}`);
102
+ return res.data;
103
+ });
104
+ }
105
+ async refreshUpdateManifest() {
106
+ const updater = this.ctx.release.github.updater;
107
+ if (!updater) {
108
+ this.logger.debug(`Skip refresh update.json because release.github.updater = false`);
109
+ return;
110
+ }
111
+ const { dist, version } = this.ctx;
112
+ const assets = globbySync(`${dist}/update*.json`).map((p) => basename(p));
113
+ const release = await this.getReleaseByTag(updater) ?? await this.createRelease({
114
+ ...this.remote,
115
+ tag_name: updater,
116
+ prerelease: true,
117
+ make_latest: "false"
118
+ });
119
+ if (!release)
120
+ throw new Error("Get or create 'release' failed.");
121
+ const existAssets = await this.client.rest.repos.listReleaseAssets({
122
+ ...this.remote,
123
+ release_id: release.id
124
+ }).then((res) => {
125
+ return res.data.filter((asset) => assets.includes(asset.name));
126
+ });
127
+ if (existAssets) {
128
+ for (const existAsset of existAssets) {
129
+ if (assets.includes(existAsset.name)) {
130
+ this.logger.debug(`Delete existed asset ${existAsset.name} in release ${updater}`);
131
+ await this.client.rest.repos.deleteReleaseAsset({
132
+ ...this.remote,
133
+ asset_id: existAsset.id
134
+ });
135
+ }
136
+ }
137
+ }
138
+ for (const asset of assets) {
139
+ await this.uploadAsset(release.id, join(dist, asset));
140
+ }
141
+ await this.client.rest.repos.updateRelease({
142
+ ...this.remote,
143
+ release_id: release.id,
144
+ name: "Release Manifest",
145
+ body: `This release is used to host \`update.json\`, please do not delete or modify it!
146
+ Updated in UTC ${( new Date()).toISOString()} for version ${version}`,
147
+ prerelease: true,
148
+ make_latest: "false"
149
+ });
150
+ }
151
+ async getChangelog() {
152
+ const { release } = this.ctx;
153
+ const { github } = release;
154
+ const { releaseNote } = github;
155
+ return releaseNote(this.ctx);
156
+ }
157
+ getClient() {
158
+ if (!env.GITHUB_TOKEN)
159
+ throw new Error("No GITHUB_TOKEN.");
160
+ const client = new Octokit({
161
+ auth: env.GITHUB_TOKEN,
162
+ userAgent: "zotero-plugin-scaffold"
163
+ });
164
+ return client;
165
+ }
166
+ get remote() {
167
+ const [owner, repo] = this.ctx.release.github.repository.split("/");
168
+ return {
169
+ owner,
170
+ repo
171
+ };
172
+ }
173
+ }
174
+
175
+ export { GitHub as default };
package/dist/cli.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import process, { exit, env } from 'node:process';
3
3
  import { Command } from '@commander-js/extra-typings';
4
4
  import updateNotifier from 'update-notifier';
5
- import { L as Log, C as Config, B as Build, S as Serve, R as Release } from './shared/zotero-plugin-scaffold.242aa92d.mjs';
5
+ import { L as Log, C as Config, a as Build, S as Serve, R as Release } from './shared/zotero-plugin-scaffold.c7c8af0c.mjs';
6
6
  import 'node:path';
7
7
  import 'c12';
8
8
  import 'es-toolkit';
@@ -19,14 +19,11 @@ import 'node:crypto';
19
19
  import 'node:child_process';
20
20
  import 'conventional-changelog';
21
21
  import 'bumpp';
22
- import 'node:fs';
23
- import '@gitee/typescript-sdk-v5';
24
- import 'mime';
25
- import 'octokit';
26
22
  import 'chokidar';
23
+ import 'node:fs';
27
24
 
28
25
  const name = "zotero-plugin-scaffold";
29
- const version = "0.1.3";
26
+ const version = "0.1.5";
30
27
 
31
28
  const logger = new Log();
32
29
  async function main() {
@@ -66,9 +63,11 @@ async function main() {
66
63
  });
67
64
  cli.parse();
68
65
  }
69
- main().catch((err) => {
66
+ main().catch(onError);
67
+ process.on("uncaughtException", onError);
68
+ function onError(err) {
70
69
  logger.error(err);
71
70
  exit(1);
72
- });
71
+ }
73
72
 
74
73
  export { main as default };
package/dist/index.d.mts CHANGED
@@ -158,17 +158,29 @@ interface Config$1 {
158
158
  /**
159
159
  * The download link of XPI.
160
160
  *
161
+ * Some placeholders are available, see Context.templateData.
162
+ *
161
163
  * XPI 文件的地址。
162
164
  *
165
+ * 一些可用的占位符请参阅 Context.templateData。
166
+ *
163
167
  * @default `https://github.com/{{owner}}/{{repo}}/release/download/v{{version}}/{{xpiName}}.xpi`
168
+ *
169
+ * @see {@link Context.templateData}
164
170
  */
165
171
  xpiDownloadLink: string;
166
172
  /**
167
173
  * The uri of update.json.
168
174
  *
175
+ * Some placeholders are available, see Context.templateData.
176
+ *
169
177
  * update.json 文件的地址。
170
178
  *
179
+ * 一些可用的占位符请参阅 Context.templateData。
180
+ *
171
181
  * @default `https://github.com/{{owner}}/{{repo}}/release/download/release/update.json`
182
+ *
183
+ * @see {@link Context.templateData}
172
184
  */
173
185
  updateURL: string;
174
186
  /**
@@ -233,6 +245,8 @@ interface BuildConfig {
233
245
  *
234
246
  * - 在构建时,脚手架使用占位符的 key 建立正则模式 `/__${key}__/g`,并将匹配到的内容替换为 `value`。
235
247
  * - 替换发生在 `assets` 下的所有文件。
248
+ *
249
+ * @see {@link Context.templateData}
236
250
  */
237
251
  define: {
238
252
  [key: string]: string;
@@ -533,6 +547,15 @@ interface ReleaseConfig {
533
547
  * @default "ci"
534
548
  */
535
549
  enable: "ci" | "local" | "always" | "false";
550
+ /**
551
+ * The information of remote repository.
552
+ *
553
+ * Will be extracted from the `repository` property in `package.json` by default.
554
+ *
555
+ * @default {{owner}}/{{repo}}
556
+ * @see {@link Context.templateData}
557
+ */
558
+ repository: string;
536
559
  /**
537
560
  * Upload update.json to release.
538
561
  *
@@ -557,15 +580,8 @@ interface ReleaseConfig {
557
580
  };
558
581
  /**
559
582
  * Release to Gitee
560
- *
561
- * @todo Not implemented yet
562
583
  */
563
- gitee: {
564
- enable: "ci" | "local" | "always" | "false";
565
- updater: string | false;
566
- comment: boolean;
567
- releaseNote: (ctx: Context) => string;
568
- };
584
+ gitee: ReleaseConfig["github"];
569
585
  hooks: Partial<ReleaseHooks>;
570
586
  }
571
587
  interface ReleaseHooks {
@@ -591,9 +607,19 @@ interface Context extends Config$1 {
591
607
  version: string;
592
608
  hooks: Hookable<Hooks>;
593
609
  logger: InstanceType<typeof Log>;
594
- templateData: {
595
- [placeholder: string]: string;
596
- };
610
+ templateData: TemplateData;
611
+ }
612
+ interface TemplateData {
613
+ /**
614
+ * `owner` and `repo` will be extracted from the `repository` property in `package.json`.
615
+ */
616
+ owner: string;
617
+ repo: string;
618
+ version: string;
619
+ isPreRelease: string;
620
+ updateJson: "update-beta.json" | "update.json" | string;
621
+ xpiName: string;
622
+ buildTime: string;
597
623
  }
598
624
 
599
625
  /**
package/dist/index.d.ts CHANGED
@@ -158,17 +158,29 @@ interface Config$1 {
158
158
  /**
159
159
  * The download link of XPI.
160
160
  *
161
+ * Some placeholders are available, see Context.templateData.
162
+ *
161
163
  * XPI 文件的地址。
162
164
  *
165
+ * 一些可用的占位符请参阅 Context.templateData。
166
+ *
163
167
  * @default `https://github.com/{{owner}}/{{repo}}/release/download/v{{version}}/{{xpiName}}.xpi`
168
+ *
169
+ * @see {@link Context.templateData}
164
170
  */
165
171
  xpiDownloadLink: string;
166
172
  /**
167
173
  * The uri of update.json.
168
174
  *
175
+ * Some placeholders are available, see Context.templateData.
176
+ *
169
177
  * update.json 文件的地址。
170
178
  *
179
+ * 一些可用的占位符请参阅 Context.templateData。
180
+ *
171
181
  * @default `https://github.com/{{owner}}/{{repo}}/release/download/release/update.json`
182
+ *
183
+ * @see {@link Context.templateData}
172
184
  */
173
185
  updateURL: string;
174
186
  /**
@@ -233,6 +245,8 @@ interface BuildConfig {
233
245
  *
234
246
  * - 在构建时,脚手架使用占位符的 key 建立正则模式 `/__${key}__/g`,并将匹配到的内容替换为 `value`。
235
247
  * - 替换发生在 `assets` 下的所有文件。
248
+ *
249
+ * @see {@link Context.templateData}
236
250
  */
237
251
  define: {
238
252
  [key: string]: string;
@@ -533,6 +547,15 @@ interface ReleaseConfig {
533
547
  * @default "ci"
534
548
  */
535
549
  enable: "ci" | "local" | "always" | "false";
550
+ /**
551
+ * The information of remote repository.
552
+ *
553
+ * Will be extracted from the `repository` property in `package.json` by default.
554
+ *
555
+ * @default {{owner}}/{{repo}}
556
+ * @see {@link Context.templateData}
557
+ */
558
+ repository: string;
536
559
  /**
537
560
  * Upload update.json to release.
538
561
  *
@@ -557,15 +580,8 @@ interface ReleaseConfig {
557
580
  };
558
581
  /**
559
582
  * Release to Gitee
560
- *
561
- * @todo Not implemented yet
562
583
  */
563
- gitee: {
564
- enable: "ci" | "local" | "always" | "false";
565
- updater: string | false;
566
- comment: boolean;
567
- releaseNote: (ctx: Context) => string;
568
- };
584
+ gitee: ReleaseConfig["github"];
569
585
  hooks: Partial<ReleaseHooks>;
570
586
  }
571
587
  interface ReleaseHooks {
@@ -591,9 +607,19 @@ interface Context extends Config$1 {
591
607
  version: string;
592
608
  hooks: Hookable<Hooks>;
593
609
  logger: InstanceType<typeof Log>;
594
- templateData: {
595
- [placeholder: string]: string;
596
- };
610
+ templateData: TemplateData;
611
+ }
612
+ interface TemplateData {
613
+ /**
614
+ * `owner` and `repo` will be extracted from the `repository` property in `package.json`.
615
+ */
616
+ owner: string;
617
+ repo: string;
618
+ version: string;
619
+ isPreRelease: string;
620
+ updateJson: "update-beta.json" | "update.json" | string;
621
+ xpiName: string;
622
+ buildTime: string;
597
623
  }
598
624
 
599
625
  /**
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { B as Build, C as Config, R as Release, S as Serve, d as defineConfig } from './shared/zotero-plugin-scaffold.242aa92d.mjs';
1
+ export { a as Build, C as Config, R as Release, S as Serve, d as defineConfig } from './shared/zotero-plugin-scaffold.c7c8af0c.mjs';
2
2
  import 'node:path';
3
3
  import 'c12';
4
4
  import 'es-toolkit';
@@ -16,8 +16,5 @@ import 'node:crypto';
16
16
  import 'node:child_process';
17
17
  import 'conventional-changelog';
18
18
  import 'bumpp';
19
- import 'node:fs';
20
- import '@gitee/typescript-sdk-v5';
21
- import 'mime';
22
- import 'octokit';
23
19
  import 'chokidar';
20
+ import 'node:fs';
@@ -0,0 +1,25 @@
1
+ import { globbySync } from 'globby';
2
+ import { isCI } from 'std-env';
3
+ import { B as Base } from './zotero-plugin-scaffold.c7c8af0c.mjs';
4
+
5
+ var __defProp = Object.defineProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __publicField = (obj, key, value) => {
8
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
9
+ return value;
10
+ };
11
+ class ReleaseBase extends Base {
12
+ constructor(ctx) {
13
+ super(ctx);
14
+ __publicField(this, "isCI");
15
+ this.isCI = isCI;
16
+ }
17
+ checkFiles() {
18
+ const { dist } = this.ctx;
19
+ if (globbySync(`${dist}/*.xpi`).length === 0) {
20
+ throw new Error("No xpi file found, are you sure you have run build?");
21
+ }
22
+ }
23
+ }
24
+
25
+ export { ReleaseBase as R };
@@ -1,4 +1,4 @@
1
- import path, { join, basename, resolve } from 'node:path';
1
+ import path, { join, resolve } from 'node:path';
2
2
  import { loadConfig as loadConfig$1 } from 'c12';
3
3
  import { isPlainObject, kebabCase, mapValues, toMerged, escapeRegExp, debounce } from 'es-toolkit';
4
4
  import fs from 'fs-extra';
@@ -15,16 +15,13 @@ import * as crypto from 'node:crypto';
15
15
  import { execSync, spawn } from 'node:child_process';
16
16
  import conventionalChangelog from 'conventional-changelog';
17
17
  import { versionBump, ProgressEvent } from 'bumpp';
18
- import fs$1, { existsSync } from 'node:fs';
19
- import { OpenAPI, RepositoriesService } from '@gitee/typescript-sdk-v5';
20
- import mime from 'mime';
21
- import { Octokit } from 'octokit';
22
18
  import chokidar from 'chokidar';
19
+ import { existsSync } from 'node:fs';
23
20
 
24
- var __defProp$9 = Object.defineProperty;
25
- var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
26
- var __publicField$9 = (obj, key, value) => {
27
- __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
21
+ var __defProp$6 = Object.defineProperty;
22
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
23
+ var __publicField$6 = (obj, key, value) => {
24
+ __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
28
25
  return value;
29
26
  };
30
27
  var LOG_LEVEL = /* @__PURE__ */ ((LOG_LEVEL2) => {
@@ -37,7 +34,7 @@ var LOG_LEVEL = /* @__PURE__ */ ((LOG_LEVEL2) => {
37
34
  })(LOG_LEVEL || {});
38
35
  class Log {
39
36
  constructor(config) {
40
- __publicField$9(this, "logLevel");
37
+ __publicField$6(this, "logLevel");
41
38
  if (!config || isCI || isDebug) {
42
39
  this.logLevel = 0 /* trace */;
43
40
  } else {
@@ -198,6 +195,8 @@ function resolveConfig(config) {
198
195
  config.updateURL = template(config.updateURL, templateData);
199
196
  config.xpiDownloadLink = template(config.xpiDownloadLink, templateData);
200
197
  config.build.define = mapValues(config.build.define, (v) => template(v, templateData));
198
+ config.release.github.repository = template(config.release.github.repository, templateData);
199
+ config.release.gitee.repository = template(config.release.gitee.repository, templateData);
201
200
  const hooks = createHooks();
202
201
  hooks.addHooks(config.build.hooks);
203
202
  hooks.addHooks(config.server.hooks);
@@ -284,6 +283,7 @@ const defaultConfig = {
284
283
  changelog: "",
285
284
  github: {
286
285
  enable: "ci",
286
+ repository: "{{owner}}/{{repo}}",
287
287
  updater: "release",
288
288
  comment: false,
289
289
  releaseNote: (ctx) => {
@@ -292,6 +292,7 @@ const defaultConfig = {
292
292
  },
293
293
  gitee: {
294
294
  enable: "false",
295
+ repository: "{{owner}}/{{repo}}",
295
296
  updater: "release",
296
297
  comment: false,
297
298
  releaseNote: (ctx) => {
@@ -310,15 +311,15 @@ function generateHashSync(filePath, algorithm) {
310
311
  return `${algorithm}:${hash}`;
311
312
  }
312
313
 
313
- var __defProp$8 = Object.defineProperty;
314
- var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
315
- var __publicField$8 = (obj, key, value) => {
316
- __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
314
+ var __defProp$5 = Object.defineProperty;
315
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
316
+ var __publicField$5 = (obj, key, value) => {
317
+ __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
317
318
  return value;
318
319
  };
319
320
  class Base {
320
321
  constructor(ctx) {
321
- __publicField$8(this, "ctx");
322
+ __publicField$5(this, "ctx");
322
323
  this.ctx = ctx;
323
324
  }
324
325
  get logger() {
@@ -326,18 +327,18 @@ class Base {
326
327
  }
327
328
  }
328
329
 
329
- var __defProp$7 = Object.defineProperty;
330
- var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
331
- var __publicField$7 = (obj, key, value) => {
332
- __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
330
+ var __defProp$4 = Object.defineProperty;
331
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
332
+ var __publicField$4 = (obj, key, value) => {
333
+ __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
333
334
  return value;
334
335
  };
335
336
  class Build extends Base {
336
337
  constructor(ctx) {
337
338
  var _a;
338
339
  super(ctx);
339
- __publicField$7(this, "buildTime");
340
- __publicField$7(this, "isPreRelease");
340
+ __publicField$4(this, "buildTime");
341
+ __publicField$4(this, "isPreRelease");
341
342
  (_a = env).NODE_ENV ?? (_a.NODE_ENV = "production");
342
343
  this.buildTime = "";
343
344
  this.isPreRelease = this.ctx.version.includes("-");
@@ -584,33 +585,7 @@ class Build extends Base {
584
585
  }
585
586
  }
586
587
 
587
- var __defProp$6 = Object.defineProperty;
588
- var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
589
- var __publicField$6 = (obj, key, value) => {
590
- __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
591
- return value;
592
- };
593
- class ReleaseBase extends Base {
594
- constructor(ctx) {
595
- super(ctx);
596
- __publicField$6(this, "isCI");
597
- this.isCI = isCI;
598
- }
599
- checkFiles() {
600
- const { dist } = this.ctx;
601
- if (globbySync(`${dist}/*.xpi`).length === 0) {
602
- throw new Error("No xpi file found, are you sure you have run build?");
603
- }
604
- }
605
- get owner() {
606
- return this.ctx.templateData.owner;
607
- }
608
- get repo() {
609
- return this.ctx.templateData.repo;
610
- }
611
- }
612
-
613
- class Bump extends ReleaseBase {
588
+ class Bump extends Base {
614
589
  constructor(ctx) {
615
590
  super(ctx);
616
591
  }
@@ -670,258 +645,6 @@ class Bump extends ReleaseBase {
670
645
  }
671
646
  }
672
647
 
673
- var __defProp$5 = Object.defineProperty;
674
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
675
- var __publicField$5 = (obj, key, value) => {
676
- __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
677
- return value;
678
- };
679
- class Gitee extends ReleaseBase {
680
- constructor() {
681
- super(...arguments);
682
- __publicField$5(this, "client", RepositoriesService);
683
- }
684
- async run() {
685
- OpenAPI.TOKEN = env.GITEE_TOKEN;
686
- if (!OpenAPI.TOKEN)
687
- throw new Error("No GITEE_TOKEN provided!");
688
- this.checkFiles();
689
- this.logger.info("Uploading XPI to Gitee...");
690
- await this.uploadXPI();
691
- this.logger.info("Refreshing update manifest...");
692
- await this.refreshUpdateManifest();
693
- }
694
- async uploadXPI() {
695
- const { version, dist, xpiName } = this.ctx;
696
- const release = await this.refreshRelease(
697
- this.ctx.release.bumpp.tag.toString().replaceAll("%s", version),
698
- `Release v${version}`,
699
- this.ctx.release.gitee.releaseNote(this.ctx)
700
- );
701
- await this.refreshAttach(release.id, join(dist, `${xpiName}.xpi`));
702
- }
703
- async refreshUpdateManifest() {
704
- const updater = this.ctx.release.gitee.updater;
705
- if (!updater) {
706
- this.logger.debug(
707
- `Skip refresh update.json because release.gitee.updater = false`
708
- );
709
- return;
710
- }
711
- const { dist, version } = this.ctx;
712
- const assets = globbySync(`${dist}/update*.json`).map((p) => basename(p));
713
- const release = await this.refreshRelease(
714
- updater,
715
- "Zotero Auto Update Manifest",
716
- `This release is used to host \`update.json\`, Updated in UTC ${( new Date()).toISOString()} for v${version}.`,
717
- true
718
- );
719
- for (const asset of assets)
720
- await this.refreshAttach(release.id, join(dist, asset));
721
- }
722
- async refreshRelease(tag, name, body, prerelease = false) {
723
- const old = await this.client.getV5ReposOwnerRepoReleasesTagsTag({
724
- owner: this.owner,
725
- repo: this.repo,
726
- tag
727
- });
728
- if (old?.id) {
729
- return this.client.patchV5ReposOwnerRepoReleasesId({
730
- owner: this.owner,
731
- repo: this.repo,
732
- name,
733
- body,
734
- prerelease,
735
- id: old.id,
736
- tagName: tag
737
- });
738
- }
739
- return this.client.postV5ReposOwnerRepoReleases({
740
- owner: this.owner,
741
- repo: this.repo,
742
- name,
743
- body,
744
- prerelease,
745
- tagName: tag,
746
- targetCommitish: "main"
747
- });
748
- }
749
- async refreshAttach(releaseId, file) {
750
- const assets = await this.client.getV5ReposOwnerRepoReleasesReleaseIdAttachFiles({
751
- owner: this.owner,
752
- repo: this.repo,
753
- releaseId
754
- });
755
- const fileBuffer = fs$1.readFileSync(file);
756
- for (const asset of assets) {
757
- if (asset.name === basename(file)) {
758
- await this.client.deleteV5ReposOwnerRepoReleasesReleaseIdAttachFilesAttachFileId({
759
- owner: this.owner,
760
- repo: this.repo,
761
- releaseId,
762
- attachFileId: asset.id
763
- }).catch((e) => this.logger.error(e));
764
- }
765
- }
766
- this.client.postV5ReposOwnerRepoReleasesReleaseIdAttachFiles({
767
- owner: this.owner,
768
- repo: this.repo,
769
- releaseId,
770
- file: new File([fileBuffer], basename(file), { type: "application/octet-stream" })
771
- });
772
- }
773
- }
774
-
775
- var __defProp$4 = Object.defineProperty;
776
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
777
- var __publicField$4 = (obj, key, value) => {
778
- __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
779
- return value;
780
- };
781
- class GitHub extends ReleaseBase {
782
- constructor(ctx) {
783
- super(ctx);
784
- __publicField$4(this, "client");
785
- this.client = this.getClient();
786
- }
787
- async run() {
788
- this.checkFiles();
789
- this.logger.info("Uploading XPI to GitHub...");
790
- await this.uploadXPI();
791
- this.logger.info("Refreshing update manifest...");
792
- await this.refreshUpdateManifest();
793
- return this.ctx;
794
- }
795
- /**
796
- * Create new release and upload XPI to asset
797
- */
798
- async uploadXPI() {
799
- const { version, dist, xpiName } = this.ctx;
800
- const release = await this.createRelease({
801
- owner: this.owner,
802
- repo: this.repo,
803
- tag_name: this.ctx.release.bumpp.tag.toString().replaceAll("%s", version),
804
- name: `Release v${version}`,
805
- body: await this.getChangelog(),
806
- prerelease: version.includes("-"),
807
- make_latest: "true"
808
- });
809
- if (!release)
810
- throw new Error("Create release failed!");
811
- this.logger.debug("Uploading xpi asset...");
812
- await this.uploadAsset(release.id, join(dist, `${xpiName}.xpi`));
813
- }
814
- async getReleaseByTag(tag) {
815
- return await this.client.rest.repos.getReleaseByTag({
816
- owner: this.owner,
817
- repo: this.repo,
818
- tag
819
- }).catch((e) => {
820
- this.logger.debug(`Release with tag ${tag} not found. ${e}`);
821
- return void 0;
822
- }).then((res) => {
823
- if (res && res.status === 200) {
824
- this.logger.debug(`Found release with tag "${tag}", id=${res.data.id}.`);
825
- return res.data;
826
- }
827
- });
828
- }
829
- async createRelease(options) {
830
- this.logger.debug("Creating release...", options);
831
- return await this.client.rest.repos.createRelease(options).catch((e) => {
832
- this.logger.error(e);
833
- throw new Error("Create release failed.");
834
- }).then((res) => {
835
- if (res.status === 201) {
836
- this.logger.debug(`Create release "${res.data.tag_name}" success, id: ${res.data.id}.`);
837
- return res.data;
838
- }
839
- });
840
- }
841
- async uploadAsset(releaseID, asset) {
842
- this.logger.debug(`Uploading ${asset} to release ${releaseID}`);
843
- return await this.client.rest.repos.uploadReleaseAsset({
844
- owner: this.owner,
845
- repo: this.repo,
846
- release_id: releaseID,
847
- data: fs.readFileSync(asset),
848
- headers: {
849
- "content-type": mime.getType(asset) || "application/octet-stream",
850
- "content-length": fs.statSync(asset).size
851
- },
852
- name: basename(asset)
853
- }).then((res) => {
854
- this.logger.debug(`Upload "${res.data.name}" success, assetId: ${res.data.id}`);
855
- return res.data;
856
- });
857
- }
858
- async refreshUpdateManifest() {
859
- const updater = this.ctx.release.github.updater;
860
- if (!updater) {
861
- this.logger.debug(`Skip refresh update.json because release.github.updater = false`);
862
- return;
863
- }
864
- const { dist, version } = this.ctx;
865
- const assets = globbySync(`${dist}/update*.json`).map((p) => basename(p));
866
- const release = await this.getReleaseByTag(updater) ?? await this.createRelease({
867
- owner: this.owner,
868
- repo: this.repo,
869
- tag_name: updater,
870
- prerelease: true,
871
- make_latest: "false"
872
- });
873
- if (!release)
874
- throw new Error("Get or create 'release' failed.");
875
- const existAssets = await this.client.rest.repos.listReleaseAssets({
876
- owner: this.owner,
877
- repo: this.repo,
878
- release_id: release.id
879
- }).then((res) => {
880
- return res.data.filter((asset) => assets.includes(asset.name));
881
- });
882
- if (existAssets) {
883
- for (const existAsset of existAssets) {
884
- if (assets.includes(existAsset.name)) {
885
- this.logger.debug(`Delete existed asset ${existAsset.name} in release ${updater}`);
886
- await this.client.rest.repos.deleteReleaseAsset({
887
- owner: this.owner,
888
- repo: this.repo,
889
- asset_id: existAsset.id
890
- });
891
- }
892
- }
893
- }
894
- for (const asset of assets) {
895
- await this.uploadAsset(release.id, join(dist, asset));
896
- }
897
- await this.client.rest.repos.updateRelease({
898
- owner: this.owner,
899
- repo: this.repo,
900
- release_id: release.id,
901
- name: "Release Manifest",
902
- body: `This release is used to host \`update.json\`, please do not delete or modify it!
903
- Updated in UTC ${( new Date()).toISOString()} for version ${version}`,
904
- prerelease: true,
905
- make_latest: "false"
906
- });
907
- }
908
- async getChangelog() {
909
- const { release } = this.ctx;
910
- const { github } = release;
911
- const { releaseNote } = github;
912
- return releaseNote(this.ctx);
913
- }
914
- getClient() {
915
- if (!env.GITHUB_TOKEN)
916
- throw new Error("No GITHUB_TOKEN.");
917
- const client = new Octokit({
918
- auth: env.GITHUB_TOKEN,
919
- userAgent: "zotero-plugin-scaffold"
920
- });
921
- return client;
922
- }
923
- }
924
-
925
648
  class Release extends Base {
926
649
  constructor(ctx) {
927
650
  super(ctx);
@@ -958,10 +681,14 @@ class Release extends Base {
958
681
  await new Bump(this.ctx).run();
959
682
  await this.ctx.hooks.callHook("release:push", this.ctx);
960
683
  this.ctx.release.changelog = this.getChangelog();
961
- if (isGitHubEnabled)
684
+ if (isGitHubEnabled) {
685
+ const { default: GitHub } = await import('../chunks/github.mjs');
962
686
  await new GitHub(this.ctx).run();
963
- if (isGiteeEnabled)
687
+ }
688
+ if (isGiteeEnabled) {
689
+ const { default: Gitee } = await import('../chunks/gitee.mjs');
964
690
  await new Gitee(this.ctx).run();
691
+ }
965
692
  await this.ctx.hooks.callHook("release:done", this.ctx);
966
693
  this.logger.success(
967
694
  `Done in ${(( new Date()).getTime() - t.getTime()) / 1e3} s.`
@@ -1398,4 +1125,4 @@ const Config = {
1398
1125
  loadConfig
1399
1126
  };
1400
1127
 
1401
- export { Build as B, Config as C, Log as L, Release as R, Serve as S, defineConfig as d };
1128
+ export { Base as B, Config as C, Log as L, Release as R, Serve as S, Build as a, defineConfig as d };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zotero-plugin-scaffold",
3
3
  "type": "module",
4
- "version": "0.1.3",
4
+ "version": "0.1.5",
5
5
  "description": "A scaffold for Zotero plugin development.",
6
6
  "author": "northword",
7
7
  "license": "AGPL-3.0-or-later",