@linkdesk/plugin-sdk 0.1.3 → 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/linkdesk-mock.generated.ts +363 -0
- package/dev-host/mock.ts +63 -25
- package/dist/bin.js +40 -6
- 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/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 +16 -13
- package/dist/vite-config.js.map +1 -1
- package/package.json +1 -1
- package/schemas/plugin.schema.json +1 -1
package/dist/dev-real.js
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `linkdesk-plugin-sdk dev --real`——E6#28.5 第三方作者真机调试环(生产 LinkDesk 秒级环,壳零新代码)。
|
|
3
|
+
*
|
|
4
|
+
* 作者在自己的插件工程根跑 `dev --real`:
|
|
5
|
+
* 1. 复用 E6#25/#15 SDK 单插件 build(defineLinkdeskPluginConfig({ real: true }))——产物 = 完整物化目录
|
|
6
|
+
* dist/<id>.linkdesk-plugin/(plugin.json + index.bundle.js + views/*.bundle.js + index.bundle.css +
|
|
7
|
+
* assets/ + i18n/ + icon…),与 .linkdesk-plugin zip 解包布局一致(壳 loader 发现 = 目录含 plugin.json)。
|
|
8
|
+
* 2. 物化目录**直写** {userData}/plugins/<id>(平台标准 %APPDATA% 等;LINKDESK_USER_PLUGINS_DIR 覆盖)
|
|
9
|
+
* ——不经 plugins:extract「存在即拒」、不碰 E6#15n boot 门禁:直写磁盘 + reload = dev 覆盖语义
|
|
10
|
+
* (生产 linkdesk:// 逐请求 readFileSync;但 protocol.handle 响应无 Cache-Control → 会被 Chromium 缓存,
|
|
11
|
+
* reload 前须清缓存才落盘生效——机制实锤 + 修正见 04-作者真机调试环.md §二/§六)。
|
|
12
|
+
* 3. watch 作者源码 → 变更自动 重建→直写→reload。作者以 `--remote-debugging-port=9222` 启动 LinkDesk
|
|
13
|
+
* (Chromium 原生 switch,壳零代码)→ SDK 经 CDP Network.clearBrowserCache + Page.reload 刷「LinkDesk Pool」窗口
|
|
14
|
+
* (清缓存后 reload 重 import 落到磁盘逐请求 readFileSync = 真机生效);
|
|
15
|
+
* 9222 同时是 CDP/AI 全自动调试入口(沿用 dev-fixtures/toast.mjs 连法)。
|
|
16
|
+
*
|
|
17
|
+
* 边界(04 档案 §六):作用域 = 作者自研 dev 插件——目标目录若已有同 id 安装(市场装发布版)会被**覆盖且不备份**;
|
|
18
|
+
* 多插件工程并行 dev 需各自独立工程;CSS 等热更走整窗口 reload(秒级,非亚秒 HMR——那是 E6#28.7 B 的候选卖点)。
|
|
19
|
+
* 作者仍不碰壳源码/构建(插件独立铁律),不造第二壳。
|
|
20
|
+
*/
|
|
21
|
+
import { copyFileSync, existsSync, mkdirSync, readdirSync, rmSync, watch } from "node:fs";
|
|
22
|
+
import { dirname, join, resolve } from "node:path";
|
|
23
|
+
import { homedir } from "node:os";
|
|
24
|
+
import { get as httpGet } from "node:http";
|
|
25
|
+
import { build } from "vite";
|
|
26
|
+
import { defineLinkdeskPluginConfig } from "./vite-config.js";
|
|
27
|
+
import { derivePluginId, readPluginManifest } from "./validate.js";
|
|
28
|
+
/** CDP reload 端口默认 9222(与壳 dev electron:dev 尾部 --remote-debugging-port=9222 对齐);LINKDESK_CDP_PORT 覆盖 */
|
|
29
|
+
export const CDP_PORT = Number(process.env.LINKDESK_CDP_PORT ?? 9222);
|
|
30
|
+
/** 作者当前平台 LinkDesk userData/plugins 代码根(Electron 默认 userData = appData/<appName>,dev/打包同名 "linkdesk")。
|
|
31
|
+
* LINKDESK_USER_PLUGINS_DIR 环境变量可覆盖(自定义安装布局 / CI 隔离 userData 的逃生门)。 */
|
|
32
|
+
export function resolveUserPluginsDir() {
|
|
33
|
+
const override = process.env.LINKDESK_USER_PLUGINS_DIR;
|
|
34
|
+
if (override && override.trim())
|
|
35
|
+
return resolve(override.trim());
|
|
36
|
+
const home = homedir();
|
|
37
|
+
switch (process.platform) {
|
|
38
|
+
case "win32":
|
|
39
|
+
return join(process.env.APPDATA ?? join(home, "AppData", "Roaming"), "linkdesk", "plugins");
|
|
40
|
+
case "darwin":
|
|
41
|
+
return join(home, "Library", "Application Support", "linkdesk", "plugins");
|
|
42
|
+
default:
|
|
43
|
+
return join(process.env.XDG_CONFIG_HOME ?? join(home, ".config"), "linkdesk", "plugins");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** 平台判定代码根目录是否已存在(首启时可能还没有——提示作者先跑一次 LinkDesk,或给 LINKDESK_USER_PLUGINS_DIR) */
|
|
47
|
+
function userPluginsDirExists() {
|
|
48
|
+
return existsSync(resolveUserPluginsDir());
|
|
49
|
+
}
|
|
50
|
+
/* ── 物化目录直写 ─────────────────────────────────────────────── */
|
|
51
|
+
/** 覆盖式深拷贝(dev 覆盖语义——rm 目标后再拷,不残留本 build 已不产出的陈旧文件)。
|
|
52
|
+
* 插件私有数据在 <appData>/linkdesk/plugins/<id>/data(另一根),删代码根不碰数据。 */
|
|
53
|
+
function copyTreeOverwrite(srcDir, destDir) {
|
|
54
|
+
mkdirSync(destDir, { recursive: true });
|
|
55
|
+
for (const e of readdirSync(srcDir, { withFileTypes: true })) {
|
|
56
|
+
const s = join(srcDir, e.name);
|
|
57
|
+
const d = join(destDir, e.name);
|
|
58
|
+
if (e.isDirectory())
|
|
59
|
+
copyTreeOverwrite(s, d);
|
|
60
|
+
else
|
|
61
|
+
copyFileSync(s, d);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** 本 build 是否有可装产物——主入口 index.bundle.js 或任一 views/<X>.bundle.js(entry 缺失的纯 views 插件形态) */
|
|
65
|
+
function hasBuildOutput(pkgDir) {
|
|
66
|
+
if (existsSync(join(pkgDir, "index.bundle.js")))
|
|
67
|
+
return true;
|
|
68
|
+
const views = join(pkgDir, "views");
|
|
69
|
+
if (existsSync(views)) {
|
|
70
|
+
try {
|
|
71
|
+
return readdirSync(views).some((f) => f.endsWith(".bundle.js"));
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
/** GET http://127.0.0.1:<port>/json/list——node:http,避免依赖全局 fetch 类型 */
|
|
80
|
+
function cdpListTargets(port) {
|
|
81
|
+
return new Promise((resolveP, rejectP) => {
|
|
82
|
+
const req = httpGet({ host: "127.0.0.1", port, path: "/json/list", timeout: 1500 }, (res) => {
|
|
83
|
+
const chunks = [];
|
|
84
|
+
res.on("data", (c) => chunks.push(c));
|
|
85
|
+
res.on("end", () => {
|
|
86
|
+
try {
|
|
87
|
+
resolveP(JSON.parse(Buffer.concat(chunks).toString("utf8")));
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
rejectP(e instanceof Error ? e : new Error(String(e)));
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
req.on("error", rejectP);
|
|
95
|
+
req.on("timeout", () => {
|
|
96
|
+
req.destroy(new Error("CDP /json/list 超时"));
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 经 CDP 刷新「LinkDesk Pool」窗口——renderer 重 import = 直写产物生效。返回是否找到并刷新成功。
|
|
102
|
+
*
|
|
103
|
+
* E6#28.5 真机自验实证(2026-09-07):单发 Page.reload 不足——`protocol.handle` 的 linkdesk:// 响应
|
|
104
|
+
* 无 Cache-Control 头 → Chromium 同 URL 二次请求命中缓存,index.bundle.js 陈旧副本永远被喂(直写磁盘
|
|
105
|
+
* 被遮蔽,protocol-debug.log 无新 200 行可证)。修复 = reload 前 Network.enable + Network.clearBrowserCache,
|
|
106
|
+
* 清掉缓存让 reload 后重 import 落到磁盘逐请求 readFileSync(纯 CDP,壳零代码)。
|
|
107
|
+
*/
|
|
108
|
+
export async function cdpReloadPool(port = CDP_PORT) {
|
|
109
|
+
let targets;
|
|
110
|
+
try {
|
|
111
|
+
targets = await cdpListTargets(port);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
const pool = targets.find((t) => t.title === "LinkDesk Pool");
|
|
117
|
+
const url = pool?.webSocketDebuggerUrl;
|
|
118
|
+
if (!pool || !url)
|
|
119
|
+
return false;
|
|
120
|
+
const Ws = globalThis.WebSocket;
|
|
121
|
+
if (!Ws) {
|
|
122
|
+
return false; // 全局 WebSocket 不可用(Node 太旧)——视为找不到,调用方打指引
|
|
123
|
+
}
|
|
124
|
+
const ws = new Ws(url);
|
|
125
|
+
await new Promise((res, rej) => {
|
|
126
|
+
ws.onopen = () => res();
|
|
127
|
+
ws.onerror = () => rej(new Error("CDP WebSocket 连接失败"));
|
|
128
|
+
});
|
|
129
|
+
// 顺序发:enable → clearBrowserCache → reload;等 reload(id 3)的回复即代表前两步已完成。
|
|
130
|
+
const reply = new Promise((res) => {
|
|
131
|
+
ws.onmessage = (ev) => {
|
|
132
|
+
const m = JSON.parse(String(ev.data));
|
|
133
|
+
if (m.id === 3)
|
|
134
|
+
res(m);
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
ws.send(JSON.stringify({ id: 1, method: "Network.enable" }));
|
|
138
|
+
ws.send(JSON.stringify({ id: 2, method: "Network.clearBrowserCache" }));
|
|
139
|
+
ws.send(JSON.stringify({ id: 3, method: "Page.reload", params: { ignoreCache: true } }));
|
|
140
|
+
await reply;
|
|
141
|
+
ws.close();
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
/* ── watch → 重建 → 直写 → reload 循环 ─────────────────────────────── */
|
|
145
|
+
/** 该路径是否不该触发重建(build 输出/依赖/元目录)——任一目录段命中即忽略 */
|
|
146
|
+
function isIgnoredRel(abs, root) {
|
|
147
|
+
const rel = abs.slice(root.length).split(/[\\/]/).filter(Boolean);
|
|
148
|
+
for (const seg of rel) {
|
|
149
|
+
if (seg === "node_modules" || seg === ".git" || seg === "dist" || seg === ".linkdesk-real")
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
// 插件分发 zip(真实态不写,防御历史遗留触发重建)
|
|
153
|
+
if (abs.endsWith(".linkdesk-plugin"))
|
|
154
|
+
return true;
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* 跑真机环并挂起进程(Ctrl+C → 关 watcher + 退出)。每次源码变更:debounce → 全量单插件 build →
|
|
159
|
+
* 直写 {userData}/plugins/<id> → CDP reload「LinkDesk Pool」。
|
|
160
|
+
*/
|
|
161
|
+
export async function runPluginDevReal(root) {
|
|
162
|
+
const pluginJson = join(root, "plugin.json");
|
|
163
|
+
if (!existsSync(pluginJson)) {
|
|
164
|
+
throw new Error(`当前目录不是插件工程——找不到 ${pluginJson}。请 cd 进插件项目根再跑 linkdesk-plugin-sdk dev --real`);
|
|
165
|
+
}
|
|
166
|
+
const manifest = readPluginManifest(pluginJson);
|
|
167
|
+
const pluginId = derivePluginId(manifest, dirname(pluginJson).split(/[\\/]/).pop() ?? "plugin");
|
|
168
|
+
const pluginsRoot = resolveUserPluginsDir();
|
|
169
|
+
const targetDir = join(pluginsRoot, pluginId);
|
|
170
|
+
const pkgDir = join(root, "dist", `${pluginId}.linkdesk-plugin`); // defineLinkdeskPluginConfig 默认 outDir="dist"
|
|
171
|
+
// 纯 manifest 无任何 js 表面(无 entry、无 contributes.views[].render)→ 无物化产物可直写,真机环无意义
|
|
172
|
+
const entry = manifest?.entry;
|
|
173
|
+
const contributes = manifest
|
|
174
|
+
?.contributes;
|
|
175
|
+
const views = contributes?.views ?? {};
|
|
176
|
+
const hasView = Object.values(views).some((arr) => Array.isArray(arr) && arr.some((vd) => typeof vd?.render === "string"));
|
|
177
|
+
if (typeof entry !== "string" && !hasView) {
|
|
178
|
+
throw new Error(`「${pluginId}」无 js 表面(无 entry、无 contributes.views[].render)——dev --real 为代码迭代环,纯 manifest 插件无需直写。`);
|
|
179
|
+
}
|
|
180
|
+
console.log("");
|
|
181
|
+
console.log(` LinkDesk 真机环(E6#28.5)→ 插件「${pluginId}」`);
|
|
182
|
+
console.log(` 直写目标:${targetDir}`);
|
|
183
|
+
console.log(` ${userPluginsDirExists() ? "✓ 定位到运行中 LinkDesk 的插件目录" : "⚠ userData/plugins 尚不存在——先启动一次 LinkDesk(首次运行会建目录)"}`);
|
|
184
|
+
console.log(` 覆盖语义:目标已存在同名安装 → 被 dev 直写覆盖且不备份(作用域 = 自研 dev 插件)`);
|
|
185
|
+
console.log(` reload:需 LinkDesk 以 --remote-debugging-port=${CDP_PORT} 启动(CDP 连不上会跳过,改码后自动重试)`);
|
|
186
|
+
console.log(` 改码 → 自动 build → 直写 → reload;Ctrl+C 停止`);
|
|
187
|
+
console.log("");
|
|
188
|
+
let stopped = false;
|
|
189
|
+
const watchers = new Set();
|
|
190
|
+
let building = false;
|
|
191
|
+
let dirty = false;
|
|
192
|
+
let reloadWarned = false;
|
|
193
|
+
/** 单次完整 cycle:build → 有产物才直写 → 通知(默认 CDP reload) */
|
|
194
|
+
async function cycle(why) {
|
|
195
|
+
console.log(`[${new Date().toLocaleTimeString()}] ${why}`);
|
|
196
|
+
try {
|
|
197
|
+
await build(defineLinkdeskPluginConfig({ real: true }));
|
|
198
|
+
}
|
|
199
|
+
catch (e) {
|
|
200
|
+
// plugin.json 正在编辑/表面编译失败 → 保留旧产物继续监听(失败不阻断循环)
|
|
201
|
+
console.error(` ✗ build 失败(保持既有直写产物):${e instanceof Error ? e.message : String(e)}`);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (!hasBuildOutput(pkgDir)) {
|
|
205
|
+
console.error(` ✗ build 无产物(${pkgDir})——跳过直写`);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
rmSync(targetDir, { recursive: true, force: true });
|
|
209
|
+
copyTreeOverwrite(pkgDir, targetDir);
|
|
210
|
+
console.log(` ✓ 直写 ${targetDir}`);
|
|
211
|
+
const reloaded = await cdpReloadPool(CDP_PORT);
|
|
212
|
+
if (reloaded) {
|
|
213
|
+
console.log(` ✓ LinkDesk Pool 已刷新(CDP ${CDP_PORT})`);
|
|
214
|
+
}
|
|
215
|
+
else if (!reloadWarned) {
|
|
216
|
+
reloadWarned = true;
|
|
217
|
+
console.log(` ⚠ 未连上 CDP ${CDP_PORT}——LinkDesk 没开?或启动时加 --remote-debugging-port=${CDP_PORT}。` +
|
|
218
|
+
`(dev electron:dev 已内置;安装版/win-unpacked 手动加同参数)后续改码会自动重试。`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/** debounce + 串行化(build 进行中再变更 → 记 dirty,结束后补一轮) */
|
|
222
|
+
let timer;
|
|
223
|
+
const schedule = (why) => {
|
|
224
|
+
if (stopped)
|
|
225
|
+
return;
|
|
226
|
+
if (timer)
|
|
227
|
+
clearTimeout(timer);
|
|
228
|
+
timer = setTimeout(() => {
|
|
229
|
+
timer = undefined;
|
|
230
|
+
void (async () => {
|
|
231
|
+
if (building) {
|
|
232
|
+
dirty = true;
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
building = true;
|
|
236
|
+
try {
|
|
237
|
+
await cycle(why);
|
|
238
|
+
if (dirty) {
|
|
239
|
+
dirty = false;
|
|
240
|
+
await cycle("变更累积,补一轮");
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
finally {
|
|
244
|
+
building = false;
|
|
245
|
+
}
|
|
246
|
+
})();
|
|
247
|
+
}, 200);
|
|
248
|
+
};
|
|
249
|
+
// 首轮:初始 build → 直写 → reload(不依赖文件事件)
|
|
250
|
+
schedule("初始 build → 直写 → reload");
|
|
251
|
+
if (stopped)
|
|
252
|
+
return;
|
|
253
|
+
// 源码 watch(root 递归;node_modules/.git/dist 等事件按路径忽略——不触发自激重建)
|
|
254
|
+
try {
|
|
255
|
+
const w = watch(root, { recursive: true }, (_event, filename) => {
|
|
256
|
+
const abs = filename ? resolve(root, String(filename)) : root;
|
|
257
|
+
if (isIgnoredRel(abs, root))
|
|
258
|
+
return;
|
|
259
|
+
schedule(`文件变更 → 重建(${String(filename)})`);
|
|
260
|
+
});
|
|
261
|
+
watchers.add(w);
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
// recursive watch 不可用(罕见平台/权限)→ 降级不 watch(作者改码后手动 Ctrl+C 重启),不阻断已装产物
|
|
265
|
+
console.error(" ⚠ 递归文件监听不可用——dev --real 降级为一次性 build 直写;改码后重启本命令生效");
|
|
266
|
+
}
|
|
267
|
+
await new Promise((stop) => {
|
|
268
|
+
const shutdown = () => {
|
|
269
|
+
stopped = true;
|
|
270
|
+
if (timer)
|
|
271
|
+
clearTimeout(timer);
|
|
272
|
+
for (const w of watchers) {
|
|
273
|
+
try {
|
|
274
|
+
w.close();
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
// 忽略关闭失败
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
stop();
|
|
281
|
+
};
|
|
282
|
+
process.once("SIGINT", shutdown);
|
|
283
|
+
process.once("SIGTERM", shutdown);
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
//# sourceMappingURL=dev-real.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-real.js","sourceRoot":"","sources":["../src/dev-real.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface GhHttpOptions {
|
|
2
|
+
/** classic PAT(repo scope)或 fine-grained token——调用方从 env/配置档/token 链路取 */
|
|
3
|
+
token: string;
|
|
4
|
+
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
5
|
+
/** 目标主机:api = api.github.com(REST 面);uploads = uploads.github.com(asset 上传面) */
|
|
6
|
+
api: "api" | "uploads";
|
|
7
|
+
/** 路径,以 / 开头,如 "/repos/encaron/demo/releases" */
|
|
8
|
+
path: string;
|
|
9
|
+
/** 追加到 path 的原始 query 串(含 ? 或纯参数字符串,按原样拼) */
|
|
10
|
+
query?: string;
|
|
11
|
+
/** 附加 header(Content-Type 等);Authorization/User-Agent/Accept 由本模块统一注入 */
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
/** 请求体:string = 自动置 Content-Type application/json;Buffer = 调用方自给 Content-Type */
|
|
14
|
+
body?: string | Buffer;
|
|
15
|
+
}
|
|
16
|
+
export interface GhHttpResult {
|
|
17
|
+
status: number;
|
|
18
|
+
ok: boolean;
|
|
19
|
+
text: string;
|
|
20
|
+
/** JSON.parse 成功则为解析值;非 JSON / 空体为 null */
|
|
21
|
+
json: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 单次 GitHub REST 请求。2xx 不抛(返回 ok:true);网络/超时抛错。
|
|
25
|
+
* 4xx/5xx 返回 ok:false + text/json 供调用方诊断(GitHub 错误体含 message 字段)。
|
|
26
|
+
*/
|
|
27
|
+
export declare function ghHttp(opts: GhHttpOptions): Promise<GhHttpResult>;
|
|
28
|
+
/** 读错误体中文诊断——GitHub 标准错误体 { message, documentation_url, ... } */
|
|
29
|
+
export declare function ghErrorDetail(res: GhHttpResult): string;
|
|
30
|
+
//# sourceMappingURL=github-http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-http.d.ts","sourceRoot":"","sources":["../src/github-http.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,gFAAgF;IAChF,GAAG,EAAE,KAAK,GAAG,SAAS,CAAC;IACvB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,IAAI,EAAE,OAAO,CAAC;CACf;AAWD;;;GAGG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAgDvE;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAMvD"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 极简 GitHub REST 客户端(E6#26b 自动发布链路底座)——`api.github.com` + `uploads.github.com`。
|
|
3
|
+
*
|
|
4
|
+
* 用 `node:https` 而非全局 fetch:SDK tsconfig `types: []` + `lib: ["ES2022"]` 无 dom/undici 类型,
|
|
5
|
+
* 全局 fetch 不可类型化——与 dev-real.ts 对 CDP 的处理同一取舍(dev-real.ts:99 注记)。Node >= 20
|
|
6
|
+
* 运行时无额外依赖。发布只走 REST:Repo 信息 / Releases(建 + 传 asset)/ Contents(读改 marketplace.json)。
|
|
7
|
+
*
|
|
8
|
+
* 失败语义:网络/超时 → throw;HTTP 非 2xx → 不抛,返回 { status, ok:false } 由调用方给中文诊断
|
|
9
|
+
* (401 token / 404 不存在 / 422 已存在等各自语义不同)。
|
|
10
|
+
*/
|
|
11
|
+
import { request as httpsRequest } from "node:https";
|
|
12
|
+
const GITHUB_API_HOST = "api.github.com";
|
|
13
|
+
const GITHUB_UPLOAD_HOST = "uploads.github.com";
|
|
14
|
+
const USER_AGENT = "linkdesk-plugin-sdk";
|
|
15
|
+
const REQUEST_TIMEOUT_MS = 30_000;
|
|
16
|
+
function collectBody(res) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
const chunks = [];
|
|
19
|
+
res.on("data", (c) => chunks.push(c));
|
|
20
|
+
res.on("error", reject);
|
|
21
|
+
res.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 单次 GitHub REST 请求。2xx 不抛(返回 ok:true);网络/超时抛错。
|
|
26
|
+
* 4xx/5xx 返回 ok:false + text/json 供调用方诊断(GitHub 错误体含 message 字段)。
|
|
27
|
+
*/
|
|
28
|
+
export async function ghHttp(opts) {
|
|
29
|
+
const host = opts.api === "uploads" ? GITHUB_UPLOAD_HOST : GITHUB_API_HOST;
|
|
30
|
+
const headers = {
|
|
31
|
+
"User-Agent": USER_AGENT,
|
|
32
|
+
Accept: "application/vnd.github+json",
|
|
33
|
+
Authorization: `Bearer ${opts.token}`,
|
|
34
|
+
...opts.headers,
|
|
35
|
+
};
|
|
36
|
+
if (typeof opts.body === "string" && !headers["Content-Type"]) {
|
|
37
|
+
headers["Content-Type"] = "application/json";
|
|
38
|
+
}
|
|
39
|
+
if (Buffer.isBuffer(opts.body) && !headers["Content-Length"]) {
|
|
40
|
+
headers["Content-Length"] = String(opts.body.length);
|
|
41
|
+
}
|
|
42
|
+
const query = opts.query ? (opts.query.startsWith("?") ? opts.query : `?${opts.query}`) : "";
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
const req = httpsRequest({
|
|
45
|
+
host,
|
|
46
|
+
path: `${opts.path}${query}`,
|
|
47
|
+
method: opts.method ?? "GET",
|
|
48
|
+
headers,
|
|
49
|
+
}, (res) => {
|
|
50
|
+
void (async () => {
|
|
51
|
+
try {
|
|
52
|
+
const text = await collectBody(res);
|
|
53
|
+
let json = null;
|
|
54
|
+
if (text.length > 0) {
|
|
55
|
+
try {
|
|
56
|
+
json = JSON.parse(text);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
json = null; // 非 JSON(罕见),保持 text 可取
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
resolve({ status: res.statusCode ?? 0, ok: (res.statusCode ?? 0) >= 200 && (res.statusCode ?? 0) < 300, text, json });
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
reject(e instanceof Error ? e : new Error(String(e)));
|
|
66
|
+
}
|
|
67
|
+
})();
|
|
68
|
+
});
|
|
69
|
+
req.on("error", (e) => reject(new Error(`GitHub 网络请求失败(${host}):${e.message}`)));
|
|
70
|
+
req.setTimeout(REQUEST_TIMEOUT_MS, () => req.destroy(new Error(`GitHub 请求超时(${REQUEST_TIMEOUT_MS}ms)`)));
|
|
71
|
+
if (opts.body)
|
|
72
|
+
req.write(opts.body);
|
|
73
|
+
req.end();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/** 读错误体中文诊断——GitHub 标准错误体 { message, documentation_url, ... } */
|
|
77
|
+
export function ghErrorDetail(res) {
|
|
78
|
+
if (res.json && typeof res.json === "object") {
|
|
79
|
+
const msg = res.json.message;
|
|
80
|
+
if (typeof msg === "string")
|
|
81
|
+
return msg;
|
|
82
|
+
}
|
|
83
|
+
return res.text.slice(0, 300);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=github-http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-http.js","sourceRoot":"","sources":["../src/github-http.ts"],"names":[],"mappings":"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"}
|
|
@@ -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":"AAmCA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yBAAyB;IACzB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,eAAe;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,yBAAyB;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAsHD,qGAAqG;AACrG,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAWlE;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWpD;AAED,sEAAsE;AACtE,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,YAAY,CAiB1F;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,kBAAkB,CAc5I;AAED,4CAA4C;AAC5C,wBAAgB,kBAAkB,IAAI,kBAAkB,CAEvD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,GAAG,kBAAkB,CAyB7G;AAED,+BAA+B;AAC/B,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,qDAAqD;AACrD,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,8CAA8C;AAC9C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE/F;AA4HD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACrB;AA8DD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4C/F"}
|