@linkdesk/plugin-sdk 0.1.2 → 0.1.6
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/dev-host/dev-main.tsx +47 -0
- package/dev-host/index.html +50 -0
- package/dev-host/linkdesk-mock.generated.ts +363 -0
- package/dev-host/mock.ts +72 -0
- package/dist/bin.js +45 -3
- package/dist/bin.js.map +1 -1
- package/dist/dev-real.d.ts +24 -0
- package/dist/dev-real.d.ts.map +1 -0
- package/dist/dev-real.js +286 -0
- package/dist/dev-real.js.map +1 -0
- package/dist/dev-server.d.ts +10 -0
- package/dist/dev-server.d.ts.map +1 -0
- package/dist/dev-server.js +136 -0
- package/dist/dev-server.js.map +1 -0
- package/dist/github-http.d.ts +30 -0
- package/dist/github-http.d.ts.map +1 -0
- package/dist/github-http.js +85 -0
- package/dist/github-http.js.map +1 -0
- package/dist/publish.d.ts +92 -0
- package/dist/publish.d.ts.map +1 -0
- package/dist/publish.js +462 -0
- package/dist/publish.js.map +1 -0
- package/dist/vite-config.d.ts +2 -0
- package/dist/vite-config.d.ts.map +1 -1
- package/dist/vite-config.js +66 -30
- package/dist/vite-config.js.map +1 -1
- package/package.json +8 -3
- package/schemas/plugin.schema.json +4 -4
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export interface GitHubRemote {
|
|
2
|
+
owner: string;
|
|
3
|
+
repo: string;
|
|
4
|
+
}
|
|
5
|
+
export interface CatalogVersion {
|
|
6
|
+
version: string;
|
|
7
|
+
downloadUrl: string;
|
|
8
|
+
publishedAt: string;
|
|
9
|
+
changelog?: string;
|
|
10
|
+
}
|
|
11
|
+
/** marketplace.json 插件条目——对齐规范 §三/§3.2 字段(作者条目=纯增量,缺字段不崩) */
|
|
12
|
+
export interface CatalogPluginEntry {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
/** 顶层 version/downloadUrl = 最新(兼容旧条目) */
|
|
16
|
+
version: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
author?: {
|
|
19
|
+
name: string;
|
|
20
|
+
url?: string;
|
|
21
|
+
};
|
|
22
|
+
icon?: string;
|
|
23
|
+
iconSource?: string;
|
|
24
|
+
category?: string;
|
|
25
|
+
downloadUrl: string;
|
|
26
|
+
size?: number;
|
|
27
|
+
publishedAt?: string;
|
|
28
|
+
minAppVersion?: string;
|
|
29
|
+
/** 版本历史,最新在前——更新机制数据源 */
|
|
30
|
+
versions: CatalogVersion[];
|
|
31
|
+
}
|
|
32
|
+
export interface MarketplaceCatalog {
|
|
33
|
+
version?: string;
|
|
34
|
+
updatedAt?: string;
|
|
35
|
+
plugins: CatalogPluginEntry[];
|
|
36
|
+
}
|
|
37
|
+
export interface PublishOptions {
|
|
38
|
+
/** 跳过确认(CI) */
|
|
39
|
+
yes?: boolean;
|
|
40
|
+
/** 只预览将做动作,不碰网络/token */
|
|
41
|
+
dryRun?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** 解析 git remote origin → owner/repo。支持 https:// / git:// / ssh://git@ / git@github.com:o/r(.git) */
|
|
44
|
+
export declare function parseGitHubRemote(raw: string): GitHubRemote | null;
|
|
45
|
+
/** 当前工程 git origin URL——非 git 工程 / 无 origin → throw(发布前提 = 插件工程已推到 GitHub) */
|
|
46
|
+
export declare function gitRemoteOrigin(root: string): string;
|
|
47
|
+
/** 作者面 manifest 摘要——entry 映射所需的字段(name/version 必填由 schema 保证,其余可选) */
|
|
48
|
+
export interface ManifestView {
|
|
49
|
+
id: string;
|
|
50
|
+
name: string;
|
|
51
|
+
version: string;
|
|
52
|
+
description?: string;
|
|
53
|
+
author?: string;
|
|
54
|
+
icon?: string;
|
|
55
|
+
iconSource?: string;
|
|
56
|
+
readme?: string;
|
|
57
|
+
}
|
|
58
|
+
export declare function collectManifestView(manifest: unknown, sourceDirName: string): ManifestView;
|
|
59
|
+
/** 单条 catalog 条目构造——versions[] 只有当前一版(合并时与既有历史拼接)。author 缺失时回落 owner。 */
|
|
60
|
+
export declare function buildCatalogEntry(v: ManifestView, downloadUrl: string, size: number, owner: string, publishedAt: string): CatalogPluginEntry;
|
|
61
|
+
/** 建空 catalog(首发的插件仓库无 marketplace.json) */
|
|
62
|
+
export declare function createEmptyCatalog(): MarketplaceCatalog;
|
|
63
|
+
/**
|
|
64
|
+
* 合并(纯函数):把新 entry 合进既有 catalog——同 id 更新(顶层 = 最新 + 历史拼接去重),
|
|
65
|
+
* 异 id 追加;其余插件条目原样保留。返回新对象,不改入参。
|
|
66
|
+
*/
|
|
67
|
+
export declare function upsertCatalogEntry(catalog: MarketplaceCatalog, entry: CatalogPluginEntry): MarketplaceCatalog;
|
|
68
|
+
/** release tag = v{version} */
|
|
69
|
+
export declare function releaseTagForVersion(version: string): string;
|
|
70
|
+
/** asset 名 = <id>.linkdesk-plugin(对齐 build 分发件命名) */
|
|
71
|
+
export declare function assetNameForId(id: string): string;
|
|
72
|
+
/** Release asset 直链——GitHub 固定形态,无需等上传响应回读 */
|
|
73
|
+
export declare function releaseDownloadUrl(remote: GitHubRemote, tag: string, assetName: string): string;
|
|
74
|
+
export interface PublishPreview {
|
|
75
|
+
id: string;
|
|
76
|
+
name: string;
|
|
77
|
+
version: string;
|
|
78
|
+
/** 完整 manifest 摘要——marketplace 条目构建数据源 */
|
|
79
|
+
view: ManifestView;
|
|
80
|
+
assetName: string;
|
|
81
|
+
assetPath: string;
|
|
82
|
+
sizeBytes: number;
|
|
83
|
+
remote: GitHubRemote;
|
|
84
|
+
tag: string;
|
|
85
|
+
releaseName: string;
|
|
86
|
+
prerelease: boolean;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* 跑发布。返回退出码(0 成功 / 1 失败)。所有失败 throw;bin catch 打印统一前缀。
|
|
90
|
+
*/
|
|
91
|
+
export declare function runPluginPublish(root: string, opts?: PublishOptions): Promise<number>;
|
|
92
|
+
//# sourceMappingURL=publish.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"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"}
|
package/dist/publish.js
ADDED
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `linkdesk-plugin-sdk publish`——E6#26d CLI 主路(自动发布链路底座 = E6#26b)。
|
|
3
|
+
*
|
|
4
|
+
* 作者在自己插件工程根跑 `npm run publish`(= linkdesk-plugin-sdk publish):
|
|
5
|
+
* 1. 读 plugin.json(复用 validate.ts 面)→ 插件 <id> v<version>;找 build 已产的分发件
|
|
6
|
+
* `<root>/<id>.linkdesk-plugin`(缺 → 提示先 `npm run build`)。
|
|
7
|
+
* 2. 目标仓库 = 工程 git remote origin(多市场源模型 01 §六——作者发布到**自己**的 GitHub 仓库,
|
|
8
|
+
* 别人把该仓库加为市场源即发现)。仅支持 github.com。
|
|
9
|
+
* 3. 自动发布链路(GitHub REST,github-http.ts):
|
|
10
|
+
* a. 校验仓库可达 + 取 default_branch(顺带验证 PAT)
|
|
11
|
+
* b. Release tag 已存在 → 拦(先 bump plugin.json version 再发)
|
|
12
|
+
* c. 创建 Release v<version> → 上传 <id>.linkdesk-plugin asset
|
|
13
|
+
* d. 更新仓库根 marketplace.json(Contents API:读 sha → 合并条目 → PUT)——
|
|
14
|
+
* 格式 = marketplace.json 规范 §三 + §3.2(versions[] 版本历史最新在前);更新消费者
|
|
15
|
+
* electron/ipc/handlers/plugin-install-handlers.ts:198 读 plugins[].versions[] 做版本对比。
|
|
16
|
+
* 4. 发前预览确认(#26b「发布前预览+确认」):打印 id/name/version/author/文件大小/目标仓库/tag
|
|
17
|
+
* → [y/N];`--yes` 跳过(CI);`--dry-run` 只打印将做动作不碰网络。
|
|
18
|
+
*
|
|
19
|
+
* PAT(#26c 链路的 CLI 半侧):env `LINKDESK_GITHUB_TOKEN` > 用户配置档
|
|
20
|
+
* `{configDir}/linkdesk-sdk/config.json`(首跑掩码提示输入存一次,0600)。
|
|
21
|
+
* #26a UI 备路 + #26c 的 app.* 配置存储 = 市场插件轮(L3)——UI 发 GitHub 需壳主进程 handler,
|
|
22
|
+
* 本 CLI 是无壳作者终端主路(00-第三方作者旅程 §五)。
|
|
23
|
+
*
|
|
24
|
+
* 失败都 throw 中文可读错误 → bin.ts catch 打印;退出码由 bin 定。
|
|
25
|
+
*/
|
|
26
|
+
import { execFileSync } from "node:child_process";
|
|
27
|
+
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
28
|
+
import { homedir } from "node:os";
|
|
29
|
+
import { basename, join, resolve } from "node:path";
|
|
30
|
+
import { createInterface } from "node:readline";
|
|
31
|
+
import { derivePluginId, readPluginManifest } from "./validate.js";
|
|
32
|
+
import { ghErrorDetail, ghHttp } from "./github-http.js";
|
|
33
|
+
/* ── token 链路(CLI 半侧)────────────────────────────────────────────── */
|
|
34
|
+
function sdkConfigDir() {
|
|
35
|
+
const home = homedir();
|
|
36
|
+
const base = process.env.APPDATA && process.platform === "win32"
|
|
37
|
+
? process.env.APPDATA
|
|
38
|
+
: process.env.XDG_CONFIG_HOME && process.platform !== "darwin"
|
|
39
|
+
? process.env.XDG_CONFIG_HOME
|
|
40
|
+
: process.platform === "darwin"
|
|
41
|
+
? join(home, "Library", "Application Support")
|
|
42
|
+
: join(home, ".config");
|
|
43
|
+
return join(base, "linkdesk-sdk");
|
|
44
|
+
}
|
|
45
|
+
function tokenFilePath() {
|
|
46
|
+
return join(sdkConfigDir(), "config.json");
|
|
47
|
+
}
|
|
48
|
+
/** 读已存 token(env 覆盖优先——CI/临时注入;文件 = 作者机器持久) */
|
|
49
|
+
function readStoredToken() {
|
|
50
|
+
const env = process.env.LINKDESK_GITHUB_TOKEN;
|
|
51
|
+
if (env && env.trim())
|
|
52
|
+
return env.trim();
|
|
53
|
+
try {
|
|
54
|
+
const raw = readFileSync(tokenFilePath(), "utf8");
|
|
55
|
+
const cfg = JSON.parse(raw);
|
|
56
|
+
if (typeof cfg.githubToken === "string" && cfg.githubToken.trim())
|
|
57
|
+
return cfg.githubToken.trim();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// 文件不存在 / 坏 JSON → 视为无 token
|
|
61
|
+
}
|
|
62
|
+
return "";
|
|
63
|
+
}
|
|
64
|
+
function writeStoredToken(token) {
|
|
65
|
+
const dir = sdkConfigDir();
|
|
66
|
+
mkdirSync(dir, { recursive: true });
|
|
67
|
+
writeFileSync(tokenFilePath(), `${JSON.stringify({ githubToken: token }, null, 2)}\n`, {
|
|
68
|
+
encoding: "utf8",
|
|
69
|
+
mode: 0o600, // POSIX 生效;Windows 忽略(ACL 由用户账户隔离)
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/** 掩码输入——stdin raw 模式逐键收,输出 '*' 不回显原文。回车/EOF 结束;Ctrl+C 取消。 */
|
|
73
|
+
function promptMasked(prompt) {
|
|
74
|
+
return new Promise((resolveP, rejectP) => {
|
|
75
|
+
const stdin = process.stdin;
|
|
76
|
+
if (!stdin.isTTY) {
|
|
77
|
+
rejectP(new Error("当前非交互终端,无法安全输入 token——请设环境变量 LINKDESK_GITHUB_TOKEN"));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
process.stdout.write(prompt);
|
|
81
|
+
let acc = "";
|
|
82
|
+
let done = false;
|
|
83
|
+
const finish = () => {
|
|
84
|
+
if (done)
|
|
85
|
+
return;
|
|
86
|
+
done = true;
|
|
87
|
+
try {
|
|
88
|
+
stdin.setRawMode(false);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// raw 模式还原失败不阻断
|
|
92
|
+
}
|
|
93
|
+
stdin.pause();
|
|
94
|
+
stdin.off("data", onData);
|
|
95
|
+
process.stdout.write("\n");
|
|
96
|
+
};
|
|
97
|
+
const onData = (buf) => {
|
|
98
|
+
for (const code of buf) {
|
|
99
|
+
if (code === 3 || code === 4) {
|
|
100
|
+
// Ctrl+C / Ctrl+D → 取消
|
|
101
|
+
finish();
|
|
102
|
+
rejectP(new Error("已取消"));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (code === 13 || code === 10) {
|
|
106
|
+
finish();
|
|
107
|
+
resolveP(acc);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (code === 8 || code === 127) {
|
|
111
|
+
if (acc.length > 0) {
|
|
112
|
+
acc = acc.slice(0, -1);
|
|
113
|
+
process.stdout.write("\b \b");
|
|
114
|
+
}
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
acc += String.fromCharCode(code);
|
|
118
|
+
process.stdout.write("*");
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
stdin.setRawMode(true);
|
|
122
|
+
stdin.resume();
|
|
123
|
+
stdin.on("data", onData);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/** 取 token:env > 文件 > (TTY 首跑)掩码提示并持久化;非 TTY 无 token → throw */
|
|
127
|
+
async function acquireToken() {
|
|
128
|
+
const env = process.env.LINKDESK_GITHUB_TOKEN;
|
|
129
|
+
if (env && env.trim())
|
|
130
|
+
return env.trim();
|
|
131
|
+
const stored = readStoredToken();
|
|
132
|
+
if (stored)
|
|
133
|
+
return stored;
|
|
134
|
+
const isTty = Boolean(process.stdin.isTTY);
|
|
135
|
+
if (!isTty) {
|
|
136
|
+
throw new Error("未找到 GitHub token:请设环境变量 LINKDESK_GITHUB_TOKEN,或先在有交互终端跑一次 publish 让它记住(存到用户配置档)。");
|
|
137
|
+
}
|
|
138
|
+
const token = await promptMasked("GitHub Personal Access Token(首次发布,需 repo 权限;仅本次输入、存入本机配置,不输出):");
|
|
139
|
+
if (!token.trim())
|
|
140
|
+
throw new Error("未输入 token,已取消");
|
|
141
|
+
writeStoredToken(token.trim());
|
|
142
|
+
console.log(" ✓ token 已存入本机配置(后续发布自动复用;env LINKDESK_GITHUB_TOKEN 可随时覆盖)");
|
|
143
|
+
return token.trim();
|
|
144
|
+
}
|
|
145
|
+
/* ── 纯逻辑:仓库解析 / 条目映射 / catalog 合并(可单测,无 I/O)────────── */
|
|
146
|
+
/** 解析 git remote origin → owner/repo。支持 https:// / git:// / ssh://git@ / git@github.com:o/r(.git) */
|
|
147
|
+
export function parseGitHubRemote(raw) {
|
|
148
|
+
const s = raw.trim();
|
|
149
|
+
const m = /^(?:https?:\/\/|git:\/\/|ssh:\/\/)?(?:git@)?github\.com[:/]([A-Za-z0-9._-]+)\/([A-Za-z0-9._-]+?)(?:\.git)?\/?$/.exec(s);
|
|
150
|
+
if (!m)
|
|
151
|
+
return null;
|
|
152
|
+
const owner = m[1];
|
|
153
|
+
const repo = m[2];
|
|
154
|
+
if (!owner || !repo)
|
|
155
|
+
return null;
|
|
156
|
+
return { owner, repo };
|
|
157
|
+
}
|
|
158
|
+
/** 当前工程 git origin URL——非 git 工程 / 无 origin → throw(发布前提 = 插件工程已推到 GitHub) */
|
|
159
|
+
export function gitRemoteOrigin(root) {
|
|
160
|
+
try {
|
|
161
|
+
const out = execFileSync("git", ["remote", "get-url", "origin"], { cwd: root, encoding: "utf8" });
|
|
162
|
+
const url = out.trim();
|
|
163
|
+
if (!url)
|
|
164
|
+
throw new Error("empty");
|
|
165
|
+
return url;
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
throw new Error("发布需要插件工程是一个已推到 GitHub 的 git 仓库(发布目标 = 工程 origin 的 Releases + marketplace.json,多市场源模型)。请先:git init → git remote add origin git@github.com:<你>/<仓库>.git → git push -u origin main,再跑 publish。");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
export function collectManifestView(manifest, sourceDirName) {
|
|
172
|
+
const id = derivePluginId(manifest, sourceDirName);
|
|
173
|
+
const m = (manifest ?? {});
|
|
174
|
+
const str = (v) => (typeof v === "string" && v.trim() ? v.trim() : undefined);
|
|
175
|
+
const name = str(m.name) ?? id;
|
|
176
|
+
const version = str(m.version);
|
|
177
|
+
if (!version)
|
|
178
|
+
throw new Error(`plugin.json 缺 version——publish 以插件版本为 Release tag(v<version>),请先声明 version`);
|
|
179
|
+
return {
|
|
180
|
+
id,
|
|
181
|
+
name,
|
|
182
|
+
version,
|
|
183
|
+
description: str(m.description),
|
|
184
|
+
author: str(m.author),
|
|
185
|
+
icon: str(m.icon),
|
|
186
|
+
iconSource: str(m.iconSource),
|
|
187
|
+
readme: str(m.readme),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/** 单条 catalog 条目构造——versions[] 只有当前一版(合并时与既有历史拼接)。author 缺失时回落 owner。 */
|
|
191
|
+
export function buildCatalogEntry(v, downloadUrl, size, owner, publishedAt) {
|
|
192
|
+
return {
|
|
193
|
+
id: v.id,
|
|
194
|
+
name: v.name,
|
|
195
|
+
version: v.version,
|
|
196
|
+
...(v.description !== undefined ? { description: v.description } : {}),
|
|
197
|
+
author: { name: v.author ?? owner },
|
|
198
|
+
...(v.icon !== undefined ? { icon: v.icon } : {}),
|
|
199
|
+
...(v.iconSource !== undefined ? { iconSource: v.iconSource } : {}),
|
|
200
|
+
downloadUrl,
|
|
201
|
+
size,
|
|
202
|
+
publishedAt,
|
|
203
|
+
versions: [{ version: v.version, downloadUrl, publishedAt }],
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
/** 建空 catalog(首发的插件仓库无 marketplace.json) */
|
|
207
|
+
export function createEmptyCatalog() {
|
|
208
|
+
return { version: "1", plugins: [] };
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* 合并(纯函数):把新 entry 合进既有 catalog——同 id 更新(顶层 = 最新 + 历史拼接去重),
|
|
212
|
+
* 异 id 追加;其余插件条目原样保留。返回新对象,不改入参。
|
|
213
|
+
*/
|
|
214
|
+
export function upsertCatalogEntry(catalog, entry) {
|
|
215
|
+
const now = entry.publishedAt ?? new Date().toISOString();
|
|
216
|
+
const next = catalog.plugins.map((p) => ({ ...p, versions: [...p.versions] }));
|
|
217
|
+
const idx = next.findIndex((p) => p.id === entry.id);
|
|
218
|
+
if (idx < 0) {
|
|
219
|
+
next.push(entry);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
const existing = next[idx];
|
|
223
|
+
const history = [
|
|
224
|
+
entry.versions[0],
|
|
225
|
+
...existing.versions.filter((v) => v.version !== entry.version), // 同版本重发 = 顶掉旧行
|
|
226
|
+
];
|
|
227
|
+
const merged = {
|
|
228
|
+
...entry,
|
|
229
|
+
versions: history,
|
|
230
|
+
// 保历史字段:新 manifest 没填的(icon/description 等)回落到旧值,避免发布抖动丢展示数据
|
|
231
|
+
icon: entry.icon ?? existing.icon,
|
|
232
|
+
iconSource: entry.iconSource ?? existing.iconSource,
|
|
233
|
+
description: entry.description ?? existing.description,
|
|
234
|
+
category: entry.category ?? existing.category,
|
|
235
|
+
minAppVersion: entry.minAppVersion ?? existing.minAppVersion,
|
|
236
|
+
};
|
|
237
|
+
next[idx] = merged;
|
|
238
|
+
}
|
|
239
|
+
return { version: catalog.version ?? "1", updatedAt: now, plugins: next };
|
|
240
|
+
}
|
|
241
|
+
/** release tag = v{version} */
|
|
242
|
+
export function releaseTagForVersion(version) {
|
|
243
|
+
return `v${version}`;
|
|
244
|
+
}
|
|
245
|
+
/** asset 名 = <id>.linkdesk-plugin(对齐 build 分发件命名) */
|
|
246
|
+
export function assetNameForId(id) {
|
|
247
|
+
return `${id}.linkdesk-plugin`;
|
|
248
|
+
}
|
|
249
|
+
/** Release asset 直链——GitHub 固定形态,无需等上传响应回读 */
|
|
250
|
+
export function releaseDownloadUrl(remote, tag, assetName) {
|
|
251
|
+
return `https://github.com/${remote.owner}/${remote.repo}/releases/download/${tag}/${assetName}`;
|
|
252
|
+
}
|
|
253
|
+
async function apiGetRepo(token, remote) {
|
|
254
|
+
const res = await ghHttp({ token, api: "api", path: `/repos/${remote.owner}/${remote.repo}` });
|
|
255
|
+
if (!res.ok) {
|
|
256
|
+
if (res.status === 401)
|
|
257
|
+
throw new Error("GitHub token 无效或无权访问——请检查 PAT(需 repo 权限)");
|
|
258
|
+
if (res.status === 404)
|
|
259
|
+
throw new Error(`仓库 ${remote.owner}/${remote.repo} 不存在或当前 token 不可见——确认已 push 到 GitHub 且仓库为 public 或 token 有权限`);
|
|
260
|
+
throw new Error(`读取仓库信息失败(${res.status}):${ghErrorDetail(res)}`);
|
|
261
|
+
}
|
|
262
|
+
const json = res.json;
|
|
263
|
+
return { defaultBranch: typeof json?.default_branch === "string" ? json.default_branch : "main" };
|
|
264
|
+
}
|
|
265
|
+
/** 查 Release 是否已存在(GET releases/tags/{tag};404 = 没有) */
|
|
266
|
+
async function apiReleaseExists(token, remote, tag) {
|
|
267
|
+
const res = await ghHttp({ token, api: "api", path: `/repos/${remote.owner}/${remote.repo}/releases/tags/${encodeURIComponent(tag)}` });
|
|
268
|
+
return res.ok;
|
|
269
|
+
}
|
|
270
|
+
/** 建 Release → 返回 release id */
|
|
271
|
+
async function apiCreateRelease(token, remote, tag, name, body, prerelease) {
|
|
272
|
+
const res = await ghHttp({
|
|
273
|
+
token,
|
|
274
|
+
api: "api",
|
|
275
|
+
method: "POST",
|
|
276
|
+
path: `/repos/${remote.owner}/${remote.repo}/releases`,
|
|
277
|
+
body: JSON.stringify({ tag_name: tag, name, body, draft: false, prerelease }),
|
|
278
|
+
});
|
|
279
|
+
if (!res.ok) {
|
|
280
|
+
if (res.status === 422)
|
|
281
|
+
throw new Error(`创建 Release v${tag} 被拒(422)——tag 可能已被占用:${ghErrorDetail(res)}`);
|
|
282
|
+
throw new Error(`创建 Release 失败(${res.status}):${ghErrorDetail(res)}`);
|
|
283
|
+
}
|
|
284
|
+
const json = res.json;
|
|
285
|
+
const id = json?.id;
|
|
286
|
+
if (typeof id !== "number")
|
|
287
|
+
throw new Error(`创建 Release 响应缺 id:${res.text.slice(0, 200)}`);
|
|
288
|
+
return id;
|
|
289
|
+
}
|
|
290
|
+
/** 上传 asset(直链走固定形态 releaseDownloadUrl,无需读响应) */
|
|
291
|
+
async function apiUploadAsset(token, remote, releaseId, assetName, data) {
|
|
292
|
+
const res = await ghHttp({
|
|
293
|
+
token,
|
|
294
|
+
api: "uploads",
|
|
295
|
+
method: "POST",
|
|
296
|
+
path: `/repos/${remote.owner}/${remote.repo}/releases/${releaseId}/assets`,
|
|
297
|
+
query: `name=${encodeURIComponent(assetName)}`,
|
|
298
|
+
headers: { "Content-Type": "application/zip" },
|
|
299
|
+
body: data,
|
|
300
|
+
});
|
|
301
|
+
if (!res.ok) {
|
|
302
|
+
throw new Error(`上传 ${assetName} 失败(${res.status}):${ghErrorDetail(res)}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/** Contents 读:取 marketplace.json 的 sha + 解码内容;404 → null(首次发布无目录文件) */
|
|
306
|
+
async function apiReadCatalog(token, remote) {
|
|
307
|
+
const res = await ghHttp({
|
|
308
|
+
token,
|
|
309
|
+
api: "api",
|
|
310
|
+
path: `/repos/${remote.owner}/${remote.repo}/contents/marketplace.json`,
|
|
311
|
+
headers: { Accept: "application/vnd.github+json" },
|
|
312
|
+
});
|
|
313
|
+
if (res.status === 404)
|
|
314
|
+
return null;
|
|
315
|
+
if (!res.ok)
|
|
316
|
+
throw new Error(`读取 marketplace.json 失败(${res.status}):${ghErrorDetail(res)}`);
|
|
317
|
+
const json = res.json;
|
|
318
|
+
const sha = json?.sha;
|
|
319
|
+
const content = json?.content;
|
|
320
|
+
if (typeof sha !== "string" || typeof content !== "string") {
|
|
321
|
+
throw new Error(`marketplace.json 响应异常(缺 sha/content):${res.text.slice(0, 200)}`);
|
|
322
|
+
}
|
|
323
|
+
const decoded = Buffer.from(content.replace(/\n/g, ""), "base64").toString("utf8");
|
|
324
|
+
let catalog;
|
|
325
|
+
try {
|
|
326
|
+
const parsed = JSON.parse(decoded);
|
|
327
|
+
if (!parsed || !Array.isArray(parsed.plugins))
|
|
328
|
+
throw new Error("plugins 数组缺失");
|
|
329
|
+
catalog = parsed;
|
|
330
|
+
}
|
|
331
|
+
catch (e) {
|
|
332
|
+
throw new Error(`现有 marketplace.json 解析失败(可能被手改坏):${e instanceof Error ? e.message : String(e)}`);
|
|
333
|
+
}
|
|
334
|
+
return { sha, catalog };
|
|
335
|
+
}
|
|
336
|
+
/** Contents 写:PUT base64 内容(带 sha 覆盖 / 无 sha 新建)。走仓库默认分支。 */
|
|
337
|
+
async function apiWriteCatalog(token, remote, id, sha, catalog) {
|
|
338
|
+
const content = `${JSON.stringify(catalog, null, 2)}\n`;
|
|
339
|
+
const body = {
|
|
340
|
+
message: `publish ${id} (marketplace.json)`,
|
|
341
|
+
content: Buffer.from(content, "utf8").toString("base64"),
|
|
342
|
+
};
|
|
343
|
+
if (sha)
|
|
344
|
+
body.sha = sha;
|
|
345
|
+
const res = await ghHttp({
|
|
346
|
+
token,
|
|
347
|
+
api: "api",
|
|
348
|
+
method: "PUT",
|
|
349
|
+
path: `/repos/${remote.owner}/${remote.repo}/contents/marketplace.json`,
|
|
350
|
+
body: JSON.stringify(body),
|
|
351
|
+
});
|
|
352
|
+
if (!res.ok) {
|
|
353
|
+
if (res.status === 409)
|
|
354
|
+
throw new Error("marketplace.json 写冲突(409)——远端刚被改动,重跑一次 publish 即可");
|
|
355
|
+
throw new Error(`更新 marketplace.json 失败(${res.status}):${ghErrorDetail(res)}`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
function collectPreview(root) {
|
|
359
|
+
const pluginJsonPath = join(root, "plugin.json");
|
|
360
|
+
if (!existsSync(pluginJsonPath)) {
|
|
361
|
+
throw new Error(`当前目录不是插件工程——找不到 ${pluginJsonPath}。请 cd 进插件项目根再跑 linkdesk-plugin-sdk publish`);
|
|
362
|
+
}
|
|
363
|
+
const manifest = readPluginManifest(pluginJsonPath);
|
|
364
|
+
const view = collectManifestView(manifest, basename(resolve(root)));
|
|
365
|
+
const assetName = assetNameForId(view.id);
|
|
366
|
+
const assetPath = join(root, assetName);
|
|
367
|
+
if (!existsSync(assetPath)) {
|
|
368
|
+
throw new Error(`找不到分发件 ${assetName}——先跑 npm run build(= linkdesk-plugin-sdk build)产出 .linkdesk-plugin 再发布`);
|
|
369
|
+
}
|
|
370
|
+
const remoteUrl = gitRemoteOrigin(root);
|
|
371
|
+
const remote = parseGitHubRemote(remoteUrl);
|
|
372
|
+
if (!remote) {
|
|
373
|
+
throw new Error(`origin 不是 github.com 仓库(当前:${remoteUrl})。发布目标 = 工程 origin 的 GitHub Releases + marketplace.json,多市场源模型仅支持 github.com`);
|
|
374
|
+
}
|
|
375
|
+
const tag = releaseTagForVersion(view.version);
|
|
376
|
+
return {
|
|
377
|
+
id: view.id,
|
|
378
|
+
name: view.name,
|
|
379
|
+
version: view.version,
|
|
380
|
+
view,
|
|
381
|
+
assetName,
|
|
382
|
+
assetPath,
|
|
383
|
+
sizeBytes: statSync(assetPath).size,
|
|
384
|
+
remote,
|
|
385
|
+
tag,
|
|
386
|
+
releaseName: `${view.name} v${view.version}`,
|
|
387
|
+
prerelease: view.version.includes("-"),
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
function renderPreview(p) {
|
|
391
|
+
const lines = [
|
|
392
|
+
"",
|
|
393
|
+
" ┌─ 发布预览 ──────────────────────────────",
|
|
394
|
+
` │ 插件 : ${p.name} v${p.version}${p.prerelease ? "(prerelease)" : ""} (${p.id})`,
|
|
395
|
+
` │ 作者 : ${p.view.author ?? p.remote.owner}`,
|
|
396
|
+
` │ 分发件 : ${p.assetName}(${(p.sizeBytes / 1024).toFixed(1)} KB)`,
|
|
397
|
+
` │ 目标仓库 : github.com/${p.remote.owner}/${p.remote.repo}(来自 git origin)`,
|
|
398
|
+
` │ 发布号 : ${p.tag}`,
|
|
399
|
+
" │ 将做 : 创建 GitHub Release → 上传 asset → 更新该仓库根 marketplace.json",
|
|
400
|
+
" └─────────────────────────────────────────",
|
|
401
|
+
];
|
|
402
|
+
return lines.join("\n");
|
|
403
|
+
}
|
|
404
|
+
/** 确认:--yes 跳过;非 TTY 无 --yes → throw(防静默发布) */
|
|
405
|
+
async function confirmPublish(yes) {
|
|
406
|
+
if (yes)
|
|
407
|
+
return;
|
|
408
|
+
const isTty = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
409
|
+
if (!isTty)
|
|
410
|
+
throw new Error("非交互终端发布需加 --yes 确认(或先 --dry-run 预览)");
|
|
411
|
+
process.stdout.write(" 发布以上内容到 GitHub?[y/N] ");
|
|
412
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
413
|
+
const answer = await new Promise((res) => rl.question("", (a) => res(a.trim().toLowerCase())));
|
|
414
|
+
rl.close();
|
|
415
|
+
if (answer !== "y" && answer !== "yes")
|
|
416
|
+
throw new Error("已取消");
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* 跑发布。返回退出码(0 成功 / 1 失败)。所有失败 throw;bin catch 打印统一前缀。
|
|
420
|
+
*/
|
|
421
|
+
export async function runPluginPublish(root, opts = {}) {
|
|
422
|
+
const preview = collectPreview(root);
|
|
423
|
+
process.stdout.write(renderPreview(preview) + "\n");
|
|
424
|
+
if (opts.dryRun) {
|
|
425
|
+
console.log(" --dry-run:以上为将执行的动作,未调用 GitHub(无网络/token 触碰)。");
|
|
426
|
+
return 0;
|
|
427
|
+
}
|
|
428
|
+
await confirmPublish(opts.yes);
|
|
429
|
+
const token = await acquireToken();
|
|
430
|
+
const { remote, tag, assetName, assetPath, version, id } = preview;
|
|
431
|
+
console.log("");
|
|
432
|
+
console.log(` publishing ${id} v${version} → github.com/${remote.owner}/${remote.repo} …`);
|
|
433
|
+
// 1. 校验仓库 + 取 default_branch(顺带验证 token)
|
|
434
|
+
await apiGetRepo(token, remote);
|
|
435
|
+
console.log(" ✓ 仓库可达、token 有效");
|
|
436
|
+
// 2. 防重发
|
|
437
|
+
if (await apiReleaseExists(token, remote, tag)) {
|
|
438
|
+
throw new Error(`Release ${tag} 已存在——该版本已发布过。要发新版本请先 bump plugin.json 的 version 再 build + publish`);
|
|
439
|
+
}
|
|
440
|
+
// 3. 建 Release + 传 asset
|
|
441
|
+
const body = preview.prerelease ? `${preview.releaseName}(prerelease,更新机制默认忽略非正式版)` : preview.releaseName;
|
|
442
|
+
const releaseId = await apiCreateRelease(token, remote, tag, preview.releaseName, body, preview.prerelease);
|
|
443
|
+
console.log(` ✓ Release ${tag} 已创建`);
|
|
444
|
+
const data = readFileSync(assetPath);
|
|
445
|
+
await apiUploadAsset(token, remote, releaseId, assetName, data);
|
|
446
|
+
const url = releaseDownloadUrl(remote, tag, assetName);
|
|
447
|
+
console.log(` ✓ asset ${assetName} 已上传`);
|
|
448
|
+
// 4. 更新 marketplace.json(含新条目 / 既有条目版本历史拼接——描述/图标等回落旧值见 upsertCatalogEntry)
|
|
449
|
+
const read = await apiReadCatalog(token, remote);
|
|
450
|
+
const existing = read ? read.catalog : createEmptyCatalog();
|
|
451
|
+
const entry = buildCatalogEntry(preview.view, url, preview.sizeBytes, remote.owner, new Date().toISOString());
|
|
452
|
+
const merged = upsertCatalogEntry(existing, entry);
|
|
453
|
+
await apiWriteCatalog(token, remote, id, read?.sha ?? null, merged);
|
|
454
|
+
console.log("");
|
|
455
|
+
console.log(` 🚀 发布成功:${id} v${version}`);
|
|
456
|
+
console.log(` Release : https://github.com/${remote.owner}/${remote.repo}/releases/tag/${tag}`);
|
|
457
|
+
console.log(` 下载直链 : ${url}`);
|
|
458
|
+
console.log(` marketplace.json 已更新(${merged.plugins.length} 个插件条目)`);
|
|
459
|
+
console.log(" 要让别人看到:对方在 LinkDesk 市场「添加市场源」填本仓库 URL 即见;想所有用户默认可见 → 申请收录官方目录。");
|
|
460
|
+
return 0;
|
|
461
|
+
}
|
|
462
|
+
//# sourceMappingURL=publish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"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"}
|
package/dist/vite-config.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export interface LinkdeskPluginOptions {
|
|
|
49
49
|
outDir?: string;
|
|
50
50
|
/** 额外 external 依赖(壳还可能提供别的共享件) */
|
|
51
51
|
external?: string[];
|
|
52
|
+
/** E6#28.5 真机环:跳过 zip 分发件与「Ready to publish」banner——只产 dist/<id>.linkdesk-plugin/ 物化目录供 dev --real 直写 */
|
|
53
|
+
real?: boolean;
|
|
52
54
|
}
|
|
53
55
|
export declare function defineLinkdeskPluginConfig(options?: LinkdeskPluginOptions): UserConfig;
|
|
54
56
|
//# sourceMappingURL=vite-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-config.d.ts","sourceRoot":"","sources":["../src/vite-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAIH,OAAO,EAAmC,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAWxE;;;6EAG6E;AAC7E,eAAO,MAAM,gBAAgB,UAA8F,CAAC;AAM5H,MAAM,WAAW,qBAAqB;IACpC,4FAA4F;IAC5F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"vite-config.d.ts","sourceRoot":"","sources":["../src/vite-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAIH,OAAO,EAAmC,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAWxE;;;6EAG6E;AAC7E,eAAO,MAAM,gBAAgB,UAA8F,CAAC;AAM5H,MAAM,WAAW,qBAAqB;IACpC,4FAA4F;IAC5F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,yGAAyG;IACzG,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAuQD,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,qBAA0B,GAAG,UAAU,CA2N1F"}
|